marked 0.2.9 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +5 -0
- package/LICENSE +1 -1
- package/README.md +313 -80
- package/component.json +10 -0
- package/doc/broken.md +426 -0
- package/doc/todo.md +2 -0
- package/lib/marked.js +273 -158
- package/man/marked.1 +4 -4
- package/package.json +2 -1
package/lib/marked.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* marked - a markdown parser
|
|
3
|
-
* Copyright (c) 2011-
|
|
3
|
+
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
|
4
4
|
* https://github.com/chjj/marked
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -17,9 +17,9 @@ var block = {
|
|
|
17
17
|
hr: /^( *[-*_]){3,} *(?:\n+|$)/,
|
|
18
18
|
heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
|
|
19
19
|
nptable: noop,
|
|
20
|
-
lheading: /^([^\n]+)\n *(=|-){
|
|
21
|
-
blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/,
|
|
22
|
-
list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
|
|
20
|
+
lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
|
|
21
|
+
blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
|
|
22
|
+
list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
|
|
23
23
|
html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,
|
|
24
24
|
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
|
|
25
25
|
table: noop,
|
|
@@ -35,13 +35,18 @@ block.item = replace(block.item, 'gm')
|
|
|
35
35
|
|
|
36
36
|
block.list = replace(block.list)
|
|
37
37
|
(/bull/g, block.bullet)
|
|
38
|
-
('hr',
|
|
38
|
+
('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
|
|
39
|
+
('def', '\\n+(?=' + block.def.source + ')')
|
|
40
|
+
();
|
|
41
|
+
|
|
42
|
+
block.blockquote = replace(block.blockquote)
|
|
43
|
+
('def', block.def)
|
|
39
44
|
();
|
|
40
45
|
|
|
41
46
|
block._tag = '(?!(?:'
|
|
42
47
|
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
|
|
43
48
|
+ '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
|
|
44
|
-
+ '|span|br|wbr|ins|del|img)\\b)\\w+(
|
|
49
|
+
+ '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
|
|
45
50
|
|
|
46
51
|
block.html = replace(block.html)
|
|
47
52
|
('comment', /<!--[\s\S]*?-->/)
|
|
@@ -75,7 +80,9 @@ block.gfm = merge({}, block.normal, {
|
|
|
75
80
|
});
|
|
76
81
|
|
|
77
82
|
block.gfm.paragraph = replace(block.paragraph)
|
|
78
|
-
('(?!', '(?!'
|
|
83
|
+
('(?!', '(?!'
|
|
84
|
+
+ block.gfm.fences.source.replace('\\1', '\\2') + '|'
|
|
85
|
+
+ block.list.source.replace('\\1', '\\3') + '|')
|
|
79
86
|
();
|
|
80
87
|
|
|
81
88
|
/**
|
|
@@ -139,7 +146,7 @@ Lexer.prototype.lex = function(src) {
|
|
|
139
146
|
* Lexing
|
|
140
147
|
*/
|
|
141
148
|
|
|
142
|
-
Lexer.prototype.token = function(src, top) {
|
|
149
|
+
Lexer.prototype.token = function(src, top, bq) {
|
|
143
150
|
var src = src.replace(/^ +$/gm, '')
|
|
144
151
|
, next
|
|
145
152
|
, loose
|
|
@@ -262,7 +269,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
262
269
|
// Pass `top` to keep the current
|
|
263
270
|
// "toplevel" state. This is exactly
|
|
264
271
|
// how markdown.pl works.
|
|
265
|
-
this.token(cap, top);
|
|
272
|
+
this.token(cap, top, true);
|
|
266
273
|
|
|
267
274
|
this.tokens.push({
|
|
268
275
|
type: 'blockquote_end'
|
|
@@ -308,7 +315,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
308
315
|
// Determine whether the next list item belongs here.
|
|
309
316
|
// Backpedal if it does not belong in this list.
|
|
310
317
|
if (this.options.smartLists && i !== l - 1) {
|
|
311
|
-
b = block.bullet.exec(cap[i+1])[0];
|
|
318
|
+
b = block.bullet.exec(cap[i + 1])[0];
|
|
312
319
|
if (bull !== b && !(bull.length > 1 && b.length > 1)) {
|
|
313
320
|
src = cap.slice(i + 1).join('\n') + src;
|
|
314
321
|
i = l - 1;
|
|
@@ -320,7 +327,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
320
327
|
// for discount behavior.
|
|
321
328
|
loose = next || /\n\n(?!\s*$)/.test(item);
|
|
322
329
|
if (i !== l - 1) {
|
|
323
|
-
next = item
|
|
330
|
+
next = item.charAt(item.length - 1) === '\n';
|
|
324
331
|
if (!loose) loose = next;
|
|
325
332
|
}
|
|
326
333
|
|
|
@@ -331,7 +338,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
331
338
|
});
|
|
332
339
|
|
|
333
340
|
// Recurse.
|
|
334
|
-
this.token(item, false);
|
|
341
|
+
this.token(item, false, bq);
|
|
335
342
|
|
|
336
343
|
this.tokens.push({
|
|
337
344
|
type: 'list_item_end'
|
|
@@ -352,14 +359,14 @@ Lexer.prototype.token = function(src, top) {
|
|
|
352
359
|
type: this.options.sanitize
|
|
353
360
|
? 'paragraph'
|
|
354
361
|
: 'html',
|
|
355
|
-
pre: cap[1] === 'pre' || cap[1] === 'script',
|
|
362
|
+
pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
|
|
356
363
|
text: cap[0]
|
|
357
364
|
});
|
|
358
365
|
continue;
|
|
359
366
|
}
|
|
360
367
|
|
|
361
368
|
// def
|
|
362
|
-
if (top && (cap = this.rules.def.exec(src))) {
|
|
369
|
+
if ((!bq && top) && (cap = this.rules.def.exec(src))) {
|
|
363
370
|
src = src.substring(cap[0].length);
|
|
364
371
|
this.tokens.links[cap[1].toLowerCase()] = {
|
|
365
372
|
href: cap[2],
|
|
@@ -407,7 +414,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
407
414
|
src = src.substring(cap[0].length);
|
|
408
415
|
this.tokens.push({
|
|
409
416
|
type: 'paragraph',
|
|
410
|
-
text: cap[1]
|
|
417
|
+
text: cap[1].charAt(cap[1].length - 1) === '\n'
|
|
411
418
|
? cap[1].slice(0, -1)
|
|
412
419
|
: cap[1]
|
|
413
420
|
});
|
|
@@ -454,8 +461,8 @@ var inline = {
|
|
|
454
461
|
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
|
|
455
462
|
};
|
|
456
463
|
|
|
457
|
-
inline._inside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;
|
|
458
|
-
inline._href = /\s*<?([
|
|
464
|
+
inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
|
|
465
|
+
inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
|
|
459
466
|
|
|
460
467
|
inline.link = replace(inline.link)
|
|
461
468
|
('inside', inline._inside)
|
|
@@ -512,6 +519,8 @@ function InlineLexer(links, options) {
|
|
|
512
519
|
this.options = options || marked.defaults;
|
|
513
520
|
this.links = links;
|
|
514
521
|
this.rules = inline.normal;
|
|
522
|
+
this.renderer = this.options.renderer || new Renderer;
|
|
523
|
+
this.renderer.options = this.options;
|
|
515
524
|
|
|
516
525
|
if (!this.links) {
|
|
517
526
|
throw new
|
|
@@ -567,7 +576,7 @@ InlineLexer.prototype.output = function(src) {
|
|
|
567
576
|
if (cap = this.rules.autolink.exec(src)) {
|
|
568
577
|
src = src.substring(cap[0].length);
|
|
569
578
|
if (cap[2] === '@') {
|
|
570
|
-
text = cap[1]
|
|
579
|
+
text = cap[1].charAt(6) === ':'
|
|
571
580
|
? this.mangle(cap[1].substring(7))
|
|
572
581
|
: this.mangle(cap[1]);
|
|
573
582
|
href = this.mangle('mailto:') + text;
|
|
@@ -575,29 +584,26 @@ InlineLexer.prototype.output = function(src) {
|
|
|
575
584
|
text = escape(cap[1]);
|
|
576
585
|
href = text;
|
|
577
586
|
}
|
|
578
|
-
out +=
|
|
579
|
-
+ href
|
|
580
|
-
+ '">'
|
|
581
|
-
+ text
|
|
582
|
-
+ '</a>';
|
|
587
|
+
out += this.renderer.link(href, null, text);
|
|
583
588
|
continue;
|
|
584
589
|
}
|
|
585
590
|
|
|
586
591
|
// url (gfm)
|
|
587
|
-
if (cap = this.rules.url.exec(src)) {
|
|
592
|
+
if (!this.inLink && (cap = this.rules.url.exec(src))) {
|
|
588
593
|
src = src.substring(cap[0].length);
|
|
589
594
|
text = escape(cap[1]);
|
|
590
595
|
href = text;
|
|
591
|
-
out +=
|
|
592
|
-
+ href
|
|
593
|
-
+ '">'
|
|
594
|
-
+ text
|
|
595
|
-
+ '</a>';
|
|
596
|
+
out += this.renderer.link(href, null, text);
|
|
596
597
|
continue;
|
|
597
598
|
}
|
|
598
599
|
|
|
599
600
|
// tag
|
|
600
601
|
if (cap = this.rules.tag.exec(src)) {
|
|
602
|
+
if (!this.inLink && /^<a /i.test(cap[0])) {
|
|
603
|
+
this.inLink = true;
|
|
604
|
+
} else if (this.inLink && /^<\/a>/i.test(cap[0])) {
|
|
605
|
+
this.inLink = false;
|
|
606
|
+
}
|
|
601
607
|
src = src.substring(cap[0].length);
|
|
602
608
|
out += this.options.sanitize
|
|
603
609
|
? escape(cap[0])
|
|
@@ -608,10 +614,12 @@ InlineLexer.prototype.output = function(src) {
|
|
|
608
614
|
// link
|
|
609
615
|
if (cap = this.rules.link.exec(src)) {
|
|
610
616
|
src = src.substring(cap[0].length);
|
|
617
|
+
this.inLink = true;
|
|
611
618
|
out += this.outputLink(cap, {
|
|
612
619
|
href: cap[2],
|
|
613
620
|
title: cap[3]
|
|
614
621
|
});
|
|
622
|
+
this.inLink = false;
|
|
615
623
|
continue;
|
|
616
624
|
}
|
|
617
625
|
|
|
@@ -622,54 +630,48 @@ InlineLexer.prototype.output = function(src) {
|
|
|
622
630
|
link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
|
|
623
631
|
link = this.links[link.toLowerCase()];
|
|
624
632
|
if (!link || !link.href) {
|
|
625
|
-
out += cap[0]
|
|
633
|
+
out += cap[0].charAt(0);
|
|
626
634
|
src = cap[0].substring(1) + src;
|
|
627
635
|
continue;
|
|
628
636
|
}
|
|
637
|
+
this.inLink = true;
|
|
629
638
|
out += this.outputLink(cap, link);
|
|
639
|
+
this.inLink = false;
|
|
630
640
|
continue;
|
|
631
641
|
}
|
|
632
642
|
|
|
633
643
|
// strong
|
|
634
644
|
if (cap = this.rules.strong.exec(src)) {
|
|
635
645
|
src = src.substring(cap[0].length);
|
|
636
|
-
out +=
|
|
637
|
-
+ this.output(cap[2] || cap[1])
|
|
638
|
-
+ '</strong>';
|
|
646
|
+
out += this.renderer.strong(this.output(cap[2] || cap[1]));
|
|
639
647
|
continue;
|
|
640
648
|
}
|
|
641
649
|
|
|
642
650
|
// em
|
|
643
651
|
if (cap = this.rules.em.exec(src)) {
|
|
644
652
|
src = src.substring(cap[0].length);
|
|
645
|
-
out +=
|
|
646
|
-
+ this.output(cap[2] || cap[1])
|
|
647
|
-
+ '</em>';
|
|
653
|
+
out += this.renderer.em(this.output(cap[2] || cap[1]));
|
|
648
654
|
continue;
|
|
649
655
|
}
|
|
650
656
|
|
|
651
657
|
// code
|
|
652
658
|
if (cap = this.rules.code.exec(src)) {
|
|
653
659
|
src = src.substring(cap[0].length);
|
|
654
|
-
out +=
|
|
655
|
-
+ escape(cap[2], true)
|
|
656
|
-
+ '</code>';
|
|
660
|
+
out += this.renderer.codespan(escape(cap[2], true));
|
|
657
661
|
continue;
|
|
658
662
|
}
|
|
659
663
|
|
|
660
664
|
// br
|
|
661
665
|
if (cap = this.rules.br.exec(src)) {
|
|
662
666
|
src = src.substring(cap[0].length);
|
|
663
|
-
out +=
|
|
667
|
+
out += this.renderer.br();
|
|
664
668
|
continue;
|
|
665
669
|
}
|
|
666
670
|
|
|
667
671
|
// del (gfm)
|
|
668
672
|
if (cap = this.rules.del.exec(src)) {
|
|
669
673
|
src = src.substring(cap[0].length);
|
|
670
|
-
out +=
|
|
671
|
-
+ this.output(cap[1])
|
|
672
|
-
+ '</del>';
|
|
674
|
+
out += this.renderer.del(this.output(cap[1]));
|
|
673
675
|
continue;
|
|
674
676
|
}
|
|
675
677
|
|
|
@@ -694,31 +696,12 @@ InlineLexer.prototype.output = function(src) {
|
|
|
694
696
|
*/
|
|
695
697
|
|
|
696
698
|
InlineLexer.prototype.outputLink = function(cap, link) {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
+ escape(link.title)
|
|
704
|
-
+ '"'
|
|
705
|
-
: '')
|
|
706
|
-
+ '>'
|
|
707
|
-
+ this.output(cap[1])
|
|
708
|
-
+ '</a>';
|
|
709
|
-
} else {
|
|
710
|
-
return '<img src="'
|
|
711
|
-
+ escape(link.href)
|
|
712
|
-
+ '" alt="'
|
|
713
|
-
+ escape(cap[1])
|
|
714
|
-
+ '"'
|
|
715
|
-
+ (link.title
|
|
716
|
-
? ' title="'
|
|
717
|
-
+ escape(link.title)
|
|
718
|
-
+ '"'
|
|
719
|
-
: '')
|
|
720
|
-
+ '>';
|
|
721
|
-
}
|
|
699
|
+
var href = escape(link.href)
|
|
700
|
+
, title = link.title ? escape(link.title) : null;
|
|
701
|
+
|
|
702
|
+
return cap[0].charAt(0) !== '!'
|
|
703
|
+
? this.renderer.link(href, title, this.output(cap[1]))
|
|
704
|
+
: this.renderer.image(href, title, escape(cap[1]));
|
|
722
705
|
};
|
|
723
706
|
|
|
724
707
|
/**
|
|
@@ -728,9 +711,17 @@ InlineLexer.prototype.outputLink = function(cap, link) {
|
|
|
728
711
|
InlineLexer.prototype.smartypants = function(text) {
|
|
729
712
|
if (!this.options.smartypants) return text;
|
|
730
713
|
return text
|
|
714
|
+
// em-dashes
|
|
731
715
|
.replace(/--/g, '\u2014')
|
|
732
|
-
|
|
733
|
-
.replace(/
|
|
716
|
+
// opening singles
|
|
717
|
+
.replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
|
|
718
|
+
// closing singles & apostrophes
|
|
719
|
+
.replace(/'/g, '\u2019')
|
|
720
|
+
// opening doubles
|
|
721
|
+
.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
|
|
722
|
+
// closing doubles
|
|
723
|
+
.replace(/"/g, '\u201d')
|
|
724
|
+
// ellipses
|
|
734
725
|
.replace(/\.{3}/g, '\u2026');
|
|
735
726
|
};
|
|
736
727
|
|
|
@@ -755,6 +746,149 @@ InlineLexer.prototype.mangle = function(text) {
|
|
|
755
746
|
return out;
|
|
756
747
|
};
|
|
757
748
|
|
|
749
|
+
/**
|
|
750
|
+
* Renderer
|
|
751
|
+
*/
|
|
752
|
+
|
|
753
|
+
function Renderer(options) {
|
|
754
|
+
this.options = options || {};
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
Renderer.prototype.code = function(code, lang, escaped) {
|
|
758
|
+
if (this.options.highlight) {
|
|
759
|
+
var out = this.options.highlight(code, lang);
|
|
760
|
+
if (out != null && out !== code) {
|
|
761
|
+
escaped = true;
|
|
762
|
+
code = out;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (!lang) {
|
|
767
|
+
return '<pre><code>'
|
|
768
|
+
+ (escaped ? code : escape(code, true))
|
|
769
|
+
+ '\n</code></pre>';
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
return '<pre><code class="'
|
|
773
|
+
+ this.options.langPrefix
|
|
774
|
+
+ escape(lang, true)
|
|
775
|
+
+ '">'
|
|
776
|
+
+ (escaped ? code : escape(code, true))
|
|
777
|
+
+ '\n</code></pre>\n';
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
Renderer.prototype.blockquote = function(quote) {
|
|
781
|
+
return '<blockquote>\n' + quote + '</blockquote>\n';
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
Renderer.prototype.html = function(html) {
|
|
785
|
+
return html;
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
Renderer.prototype.heading = function(text, level, raw) {
|
|
789
|
+
return '<h'
|
|
790
|
+
+ level
|
|
791
|
+
+ ' id="'
|
|
792
|
+
+ this.options.headerPrefix
|
|
793
|
+
+ raw.toLowerCase().replace(/[^\w]+/g, '-')
|
|
794
|
+
+ '">'
|
|
795
|
+
+ text
|
|
796
|
+
+ '</h'
|
|
797
|
+
+ level
|
|
798
|
+
+ '>\n';
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
Renderer.prototype.hr = function() {
|
|
802
|
+
return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
Renderer.prototype.list = function(body, ordered) {
|
|
806
|
+
var type = ordered ? 'ol' : 'ul';
|
|
807
|
+
return '<' + type + '>\n' + body + '</' + type + '>\n';
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
Renderer.prototype.listitem = function(text) {
|
|
811
|
+
return '<li>' + text + '</li>\n';
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
Renderer.prototype.paragraph = function(text) {
|
|
815
|
+
return '<p>' + text + '</p>\n';
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
Renderer.prototype.table = function(header, body) {
|
|
819
|
+
return '<table>\n'
|
|
820
|
+
+ '<thead>\n'
|
|
821
|
+
+ header
|
|
822
|
+
+ '</thead>\n'
|
|
823
|
+
+ '<tbody>\n'
|
|
824
|
+
+ body
|
|
825
|
+
+ '</tbody>\n'
|
|
826
|
+
+ '</table>\n';
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
Renderer.prototype.tablerow = function(content) {
|
|
830
|
+
return '<tr>\n' + content + '</tr>\n';
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
Renderer.prototype.tablecell = function(content, flags) {
|
|
834
|
+
var type = flags.header ? 'th' : 'td';
|
|
835
|
+
var tag = flags.align
|
|
836
|
+
? '<' + type + ' style="text-align:' + flags.align + '">'
|
|
837
|
+
: '<' + type + '>';
|
|
838
|
+
return tag + content + '</' + type + '>\n';
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
// span level renderer
|
|
842
|
+
Renderer.prototype.strong = function(text) {
|
|
843
|
+
return '<strong>' + text + '</strong>';
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
Renderer.prototype.em = function(text) {
|
|
847
|
+
return '<em>' + text + '</em>';
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
Renderer.prototype.codespan = function(text) {
|
|
851
|
+
return '<code>' + text + '</code>';
|
|
852
|
+
};
|
|
853
|
+
|
|
854
|
+
Renderer.prototype.br = function() {
|
|
855
|
+
return this.options.xhtml ? '<br/>' : '<br>';
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
Renderer.prototype.del = function(text) {
|
|
859
|
+
return '<del>' + text + '</del>';
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
Renderer.prototype.link = function(href, title, text) {
|
|
863
|
+
if (this.options.sanitize) {
|
|
864
|
+
try {
|
|
865
|
+
var prot = decodeURIComponent(unescape(href))
|
|
866
|
+
.replace(/[^\w:]/g, '')
|
|
867
|
+
.toLowerCase();
|
|
868
|
+
} catch (e) {
|
|
869
|
+
return '';
|
|
870
|
+
}
|
|
871
|
+
if (prot.indexOf('javascript:') === 0) {
|
|
872
|
+
return '';
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
var out = '<a href="' + href + '"';
|
|
876
|
+
if (title) {
|
|
877
|
+
out += ' title="' + title + '"';
|
|
878
|
+
}
|
|
879
|
+
out += '>' + text + '</a>';
|
|
880
|
+
return out;
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
Renderer.prototype.image = function(href, title, text) {
|
|
884
|
+
var out = '<img src="' + href + '" alt="' + text + '"';
|
|
885
|
+
if (title) {
|
|
886
|
+
out += ' title="' + title + '"';
|
|
887
|
+
}
|
|
888
|
+
out += this.options.xhtml ? '/>' : '>';
|
|
889
|
+
return out;
|
|
890
|
+
};
|
|
891
|
+
|
|
758
892
|
/**
|
|
759
893
|
* Parsing & Compiling
|
|
760
894
|
*/
|
|
@@ -763,14 +897,17 @@ function Parser(options) {
|
|
|
763
897
|
this.tokens = [];
|
|
764
898
|
this.token = null;
|
|
765
899
|
this.options = options || marked.defaults;
|
|
900
|
+
this.options.renderer = this.options.renderer || new Renderer;
|
|
901
|
+
this.renderer = this.options.renderer;
|
|
902
|
+
this.renderer.options = this.options;
|
|
766
903
|
}
|
|
767
904
|
|
|
768
905
|
/**
|
|
769
906
|
* Static Parse Method
|
|
770
907
|
*/
|
|
771
908
|
|
|
772
|
-
Parser.parse = function(src, options) {
|
|
773
|
-
var parser = new Parser(options);
|
|
909
|
+
Parser.parse = function(src, options, renderer) {
|
|
910
|
+
var parser = new Parser(options, renderer);
|
|
774
911
|
return parser.parse(src);
|
|
775
912
|
};
|
|
776
913
|
|
|
@@ -779,7 +916,7 @@ Parser.parse = function(src, options) {
|
|
|
779
916
|
*/
|
|
780
917
|
|
|
781
918
|
Parser.prototype.parse = function(src) {
|
|
782
|
-
this.inline = new InlineLexer(src.links, this.options);
|
|
919
|
+
this.inline = new InlineLexer(src.links, this.options, this.renderer);
|
|
783
920
|
this.tokens = src.reverse();
|
|
784
921
|
|
|
785
922
|
var out = '';
|
|
@@ -803,7 +940,7 @@ Parser.prototype.next = function() {
|
|
|
803
940
|
*/
|
|
804
941
|
|
|
805
942
|
Parser.prototype.peek = function() {
|
|
806
|
-
return this.tokens[this.tokens.length-1] || 0;
|
|
943
|
+
return this.tokens[this.tokens.length - 1] || 0;
|
|
807
944
|
};
|
|
808
945
|
|
|
809
946
|
/**
|
|
@@ -830,77 +967,53 @@ Parser.prototype.tok = function() {
|
|
|
830
967
|
return '';
|
|
831
968
|
}
|
|
832
969
|
case 'hr': {
|
|
833
|
-
return
|
|
970
|
+
return this.renderer.hr();
|
|
834
971
|
}
|
|
835
972
|
case 'heading': {
|
|
836
|
-
return
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
+ '</h'
|
|
841
|
-
+ this.token.depth
|
|
842
|
-
+ '>\n';
|
|
973
|
+
return this.renderer.heading(
|
|
974
|
+
this.inline.output(this.token.text),
|
|
975
|
+
this.token.depth,
|
|
976
|
+
this.token.text);
|
|
843
977
|
}
|
|
844
978
|
case 'code': {
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
this.token.escaped = true;
|
|
849
|
-
this.token.text = code;
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
if (!this.token.escaped) {
|
|
854
|
-
this.token.text = escape(this.token.text, true);
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
return '<pre><code'
|
|
858
|
-
+ (this.token.lang
|
|
859
|
-
? ' class="'
|
|
860
|
-
+ this.options.langPrefix
|
|
861
|
-
+ this.token.lang
|
|
862
|
-
+ '"'
|
|
863
|
-
: '')
|
|
864
|
-
+ '>'
|
|
865
|
-
+ this.token.text
|
|
866
|
-
+ '</code></pre>\n';
|
|
979
|
+
return this.renderer.code(this.token.text,
|
|
980
|
+
this.token.lang,
|
|
981
|
+
this.token.escaped);
|
|
867
982
|
}
|
|
868
983
|
case 'table': {
|
|
869
|
-
var
|
|
870
|
-
,
|
|
984
|
+
var header = ''
|
|
985
|
+
, body = ''
|
|
871
986
|
, i
|
|
872
987
|
, row
|
|
873
988
|
, cell
|
|
989
|
+
, flags
|
|
874
990
|
, j;
|
|
875
991
|
|
|
876
992
|
// header
|
|
877
|
-
|
|
993
|
+
cell = '';
|
|
878
994
|
for (i = 0; i < this.token.header.length; i++) {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
:
|
|
995
|
+
flags = { header: true, align: this.token.align[i] };
|
|
996
|
+
cell += this.renderer.tablecell(
|
|
997
|
+
this.inline.output(this.token.header[i]),
|
|
998
|
+
{ header: true, align: this.token.align[i] }
|
|
999
|
+
);
|
|
883
1000
|
}
|
|
884
|
-
|
|
1001
|
+
header += this.renderer.tablerow(cell);
|
|
885
1002
|
|
|
886
|
-
// body
|
|
887
|
-
body += '<tbody>\n'
|
|
888
1003
|
for (i = 0; i < this.token.cells.length; i++) {
|
|
889
1004
|
row = this.token.cells[i];
|
|
890
|
-
|
|
1005
|
+
|
|
1006
|
+
cell = '';
|
|
891
1007
|
for (j = 0; j < row.length; j++) {
|
|
892
|
-
cell
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1008
|
+
cell += this.renderer.tablecell(
|
|
1009
|
+
this.inline.output(row[j]),
|
|
1010
|
+
{ header: false, align: this.token.align[j] }
|
|
1011
|
+
);
|
|
896
1012
|
}
|
|
897
|
-
body += '</tr>\n';
|
|
898
|
-
}
|
|
899
|
-
body += '</tbody>\n';
|
|
900
1013
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1014
|
+
body += this.renderer.tablerow(cell);
|
|
1015
|
+
}
|
|
1016
|
+
return this.renderer.table(header, body);
|
|
904
1017
|
}
|
|
905
1018
|
case 'blockquote_start': {
|
|
906
1019
|
var body = '';
|
|
@@ -909,25 +1022,17 @@ Parser.prototype.tok = function() {
|
|
|
909
1022
|
body += this.tok();
|
|
910
1023
|
}
|
|
911
1024
|
|
|
912
|
-
return
|
|
913
|
-
+ body
|
|
914
|
-
+ '</blockquote>\n';
|
|
1025
|
+
return this.renderer.blockquote(body);
|
|
915
1026
|
}
|
|
916
1027
|
case 'list_start': {
|
|
917
|
-
var
|
|
918
|
-
,
|
|
1028
|
+
var body = ''
|
|
1029
|
+
, ordered = this.token.ordered;
|
|
919
1030
|
|
|
920
1031
|
while (this.next().type !== 'list_end') {
|
|
921
1032
|
body += this.tok();
|
|
922
1033
|
}
|
|
923
1034
|
|
|
924
|
-
return
|
|
925
|
-
+ type
|
|
926
|
-
+ '>\n'
|
|
927
|
-
+ body
|
|
928
|
-
+ '</'
|
|
929
|
-
+ type
|
|
930
|
-
+ '>\n';
|
|
1035
|
+
return this.renderer.list(body, ordered);
|
|
931
1036
|
}
|
|
932
1037
|
case 'list_item_start': {
|
|
933
1038
|
var body = '';
|
|
@@ -938,9 +1043,7 @@ Parser.prototype.tok = function() {
|
|
|
938
1043
|
: this.tok();
|
|
939
1044
|
}
|
|
940
1045
|
|
|
941
|
-
return
|
|
942
|
-
+ body
|
|
943
|
-
+ '</li>\n';
|
|
1046
|
+
return this.renderer.listitem(body);
|
|
944
1047
|
}
|
|
945
1048
|
case 'loose_item_start': {
|
|
946
1049
|
var body = '';
|
|
@@ -949,24 +1052,19 @@ Parser.prototype.tok = function() {
|
|
|
949
1052
|
body += this.tok();
|
|
950
1053
|
}
|
|
951
1054
|
|
|
952
|
-
return
|
|
953
|
-
+ body
|
|
954
|
-
+ '</li>\n';
|
|
1055
|
+
return this.renderer.listitem(body);
|
|
955
1056
|
}
|
|
956
1057
|
case 'html': {
|
|
957
|
-
|
|
1058
|
+
var html = !this.token.pre && !this.options.pedantic
|
|
958
1059
|
? this.inline.output(this.token.text)
|
|
959
1060
|
: this.token.text;
|
|
1061
|
+
return this.renderer.html(html);
|
|
960
1062
|
}
|
|
961
1063
|
case 'paragraph': {
|
|
962
|
-
return
|
|
963
|
-
+ this.inline.output(this.token.text)
|
|
964
|
-
+ '</p>\n';
|
|
1064
|
+
return this.renderer.paragraph(this.inline.output(this.token.text));
|
|
965
1065
|
}
|
|
966
1066
|
case 'text': {
|
|
967
|
-
return
|
|
968
|
-
+ this.parseText()
|
|
969
|
-
+ '</p>\n';
|
|
1067
|
+
return this.renderer.paragraph(this.parseText());
|
|
970
1068
|
}
|
|
971
1069
|
}
|
|
972
1070
|
};
|
|
@@ -984,6 +1082,19 @@ function escape(html, encode) {
|
|
|
984
1082
|
.replace(/'/g, ''');
|
|
985
1083
|
}
|
|
986
1084
|
|
|
1085
|
+
function unescape(html) {
|
|
1086
|
+
return html.replace(/&([#\w]+);/g, function(_, n) {
|
|
1087
|
+
n = n.toLowerCase();
|
|
1088
|
+
if (n === 'colon') return ':';
|
|
1089
|
+
if (n.charAt(0) === '#') {
|
|
1090
|
+
return n.charAt(1) === 'x'
|
|
1091
|
+
? String.fromCharCode(parseInt(n.substring(2), 16))
|
|
1092
|
+
: String.fromCharCode(+n.substring(1));
|
|
1093
|
+
}
|
|
1094
|
+
return '';
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
|
|
987
1098
|
function replace(regex, opt) {
|
|
988
1099
|
regex = regex.source;
|
|
989
1100
|
opt = opt || '';
|
|
@@ -1016,6 +1127,7 @@ function merge(obj) {
|
|
|
1016
1127
|
return obj;
|
|
1017
1128
|
}
|
|
1018
1129
|
|
|
1130
|
+
|
|
1019
1131
|
/**
|
|
1020
1132
|
* Marked
|
|
1021
1133
|
*/
|
|
@@ -1027,7 +1139,7 @@ function marked(src, opt, callback) {
|
|
|
1027
1139
|
opt = null;
|
|
1028
1140
|
}
|
|
1029
1141
|
|
|
1030
|
-
|
|
1142
|
+
opt = merge({}, marked.defaults, opt || {});
|
|
1031
1143
|
|
|
1032
1144
|
var highlight = opt.highlight
|
|
1033
1145
|
, tokens
|
|
@@ -1042,13 +1154,9 @@ function marked(src, opt, callback) {
|
|
|
1042
1154
|
|
|
1043
1155
|
pending = tokens.length;
|
|
1044
1156
|
|
|
1045
|
-
var done = function(
|
|
1157
|
+
var done = function() {
|
|
1046
1158
|
var out, err;
|
|
1047
1159
|
|
|
1048
|
-
if (hi !== true) {
|
|
1049
|
-
delete opt.highlight;
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
1160
|
try {
|
|
1053
1161
|
out = Parser.parse(tokens, opt);
|
|
1054
1162
|
} catch (e) {
|
|
@@ -1063,9 +1171,11 @@ function marked(src, opt, callback) {
|
|
|
1063
1171
|
};
|
|
1064
1172
|
|
|
1065
1173
|
if (!highlight || highlight.length < 3) {
|
|
1066
|
-
return done(
|
|
1174
|
+
return done();
|
|
1067
1175
|
}
|
|
1068
1176
|
|
|
1177
|
+
delete opt.highlight;
|
|
1178
|
+
|
|
1069
1179
|
if (!pending) return done();
|
|
1070
1180
|
|
|
1071
1181
|
for (; i < tokens.length; i++) {
|
|
@@ -1120,7 +1230,10 @@ marked.defaults = {
|
|
|
1120
1230
|
silent: false,
|
|
1121
1231
|
highlight: null,
|
|
1122
1232
|
langPrefix: 'lang-',
|
|
1123
|
-
smartypants: false
|
|
1233
|
+
smartypants: false,
|
|
1234
|
+
headerPrefix: '',
|
|
1235
|
+
renderer: new Renderer,
|
|
1236
|
+
xhtml: false
|
|
1124
1237
|
};
|
|
1125
1238
|
|
|
1126
1239
|
/**
|
|
@@ -1130,6 +1243,8 @@ marked.defaults = {
|
|
|
1130
1243
|
marked.Parser = Parser;
|
|
1131
1244
|
marked.parser = Parser.parse;
|
|
1132
1245
|
|
|
1246
|
+
marked.Renderer = Renderer;
|
|
1247
|
+
|
|
1133
1248
|
marked.Lexer = Lexer;
|
|
1134
1249
|
marked.lexer = Lexer.lex;
|
|
1135
1250
|
|