marked 0.3.17 → 0.5.0
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/.editorconfig +16 -0
- package/.eslintignore +1 -0
- package/.eslintrc.json +2 -1
- package/.travis.yml +43 -12
- package/README.md +32 -56
- package/bin/marked +24 -16
- package/bower.json +1 -1
- package/component.json +1 -1
- package/jasmine.json +11 -0
- package/lib/marked.js +345 -155
- package/man/marked.1 +2 -2
- package/man/marked.1.txt +1 -1
- package/marked.min.js +2 -2
- package/package.json +16 -5
- package/AUTHORS.md +0 -45
- package/CONTRIBUTING.md +0 -95
- package/LICENSE.md +0 -43
- package/RELEASE.md +0 -24
- package/USAGE_ADVANCED.md +0 -71
- package/USAGE_EXTENSIBILITY.md +0 -136
- package/doc/broken.md +0 -426
- package/doc/todo.md +0 -2
package/lib/marked.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* marked - a markdown parser
|
|
3
3
|
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
|
4
|
-
* https://github.com/
|
|
4
|
+
* https://github.com/markedjs/marked
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
;(function(root) {
|
|
@@ -16,20 +16,29 @@ var block = {
|
|
|
16
16
|
code: /^( {4}[^\n]+\n*)+/,
|
|
17
17
|
fences: noop,
|
|
18
18
|
hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
|
|
19
|
-
heading: /^ *(#{1,6}) *([^\n]+?)
|
|
19
|
+
heading: /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,
|
|
20
20
|
nptable: noop,
|
|
21
21
|
blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
|
|
22
22
|
list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
|
|
23
|
-
html:
|
|
23
|
+
html: '^ {0,3}(?:' // optional indentation
|
|
24
|
+
+ '<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
|
|
25
|
+
+ '|comment[^\\n]*(\\n+|$)' // (2)
|
|
26
|
+
+ '|<\\?[\\s\\S]*?\\?>\\n*' // (3)
|
|
27
|
+
+ '|<![A-Z][\\s\\S]*?>\\n*' // (4)
|
|
28
|
+
+ '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\n*' // (5)
|
|
29
|
+
+ '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)' // (6)
|
|
30
|
+
+ '|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) open tag
|
|
31
|
+
+ '|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) closing tag
|
|
32
|
+
+ ')',
|
|
24
33
|
def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
|
|
25
34
|
table: noop,
|
|
26
35
|
lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
|
|
27
|
-
paragraph: /^([^\n]+(?:\n
|
|
36
|
+
paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,
|
|
28
37
|
text: /^[^\n]+/
|
|
29
38
|
};
|
|
30
39
|
|
|
31
|
-
block._label = /(?:\\[\[\]]|[^\[\]])+/;
|
|
32
|
-
block._title = /(?:"(?:\\"
|
|
40
|
+
block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
|
|
41
|
+
block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
|
|
33
42
|
block.def = edit(block.def)
|
|
34
43
|
.replace('label', block._label)
|
|
35
44
|
.replace('title', block._title)
|
|
@@ -47,23 +56,24 @@ block.list = edit(block.list)
|
|
|
47
56
|
.replace('def', '\\n+(?=' + block.def.source + ')')
|
|
48
57
|
.getRegex();
|
|
49
58
|
|
|
50
|
-
block._tag = '
|
|
51
|
-
+ '
|
|
52
|
-
+ '|
|
|
53
|
-
+ '|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
.replace('
|
|
59
|
-
.replace(
|
|
59
|
+
block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
|
|
60
|
+
+ '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
|
|
61
|
+
+ '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
|
|
62
|
+
+ '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
|
|
63
|
+
+ '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
|
|
64
|
+
+ '|track|ul';
|
|
65
|
+
block._comment = /<!--(?!-?>)[\s\S]*?-->/;
|
|
66
|
+
block.html = edit(block.html, 'i')
|
|
67
|
+
.replace('comment', block._comment)
|
|
68
|
+
.replace('tag', block._tag)
|
|
69
|
+
.replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
|
|
60
70
|
.getRegex();
|
|
61
71
|
|
|
62
72
|
block.paragraph = edit(block.paragraph)
|
|
63
73
|
.replace('hr', block.hr)
|
|
64
74
|
.replace('heading', block.heading)
|
|
65
75
|
.replace('lheading', block.lheading)
|
|
66
|
-
.replace('tag',
|
|
76
|
+
.replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
|
|
67
77
|
.getRegex();
|
|
68
78
|
|
|
69
79
|
block.blockquote = edit(block.blockquote)
|
|
@@ -97,8 +107,26 @@ block.gfm.paragraph = edit(block.paragraph)
|
|
|
97
107
|
*/
|
|
98
108
|
|
|
99
109
|
block.tables = merge({}, block.gfm, {
|
|
100
|
-
nptable: /^ *(
|
|
101
|
-
table: /^ *\|(.+)\n
|
|
110
|
+
nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
|
|
111
|
+
table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Pedantic grammar
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
block.pedantic = merge({}, block.normal, {
|
|
119
|
+
html: edit(
|
|
120
|
+
'^ *(?:comment *(?:\\n|\\s*$)'
|
|
121
|
+
+ '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
|
|
122
|
+
+ '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
|
|
123
|
+
.replace('comment', block._comment)
|
|
124
|
+
.replace(/tag/g, '(?!(?:'
|
|
125
|
+
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
|
|
126
|
+
+ '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
|
|
127
|
+
+ '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
|
|
128
|
+
.getRegex(),
|
|
129
|
+
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/
|
|
102
130
|
});
|
|
103
131
|
|
|
104
132
|
/**
|
|
@@ -107,11 +135,13 @@ block.tables = merge({}, block.gfm, {
|
|
|
107
135
|
|
|
108
136
|
function Lexer(options) {
|
|
109
137
|
this.tokens = [];
|
|
110
|
-
this.tokens.links =
|
|
138
|
+
this.tokens.links = Object.create(null);
|
|
111
139
|
this.options = options || marked.defaults;
|
|
112
140
|
this.rules = block.normal;
|
|
113
141
|
|
|
114
|
-
if (this.options.
|
|
142
|
+
if (this.options.pedantic) {
|
|
143
|
+
this.rules = block.pedantic;
|
|
144
|
+
} else if (this.options.gfm) {
|
|
115
145
|
if (this.options.tables) {
|
|
116
146
|
this.rules = block.tables;
|
|
117
147
|
} else {
|
|
@@ -161,10 +191,16 @@ Lexer.prototype.token = function(src, top) {
|
|
|
161
191
|
bull,
|
|
162
192
|
b,
|
|
163
193
|
item,
|
|
194
|
+
listStart,
|
|
195
|
+
listItems,
|
|
196
|
+
t,
|
|
164
197
|
space,
|
|
165
198
|
i,
|
|
166
199
|
tag,
|
|
167
|
-
l
|
|
200
|
+
l,
|
|
201
|
+
isordered,
|
|
202
|
+
istask,
|
|
203
|
+
ischecked;
|
|
168
204
|
|
|
169
205
|
while (src) {
|
|
170
206
|
// newline
|
|
@@ -184,7 +220,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
184
220
|
this.tokens.push({
|
|
185
221
|
type: 'code',
|
|
186
222
|
text: !this.options.pedantic
|
|
187
|
-
? cap
|
|
223
|
+
? rtrim(cap, '\n')
|
|
188
224
|
: cap
|
|
189
225
|
});
|
|
190
226
|
continue;
|
|
@@ -214,34 +250,36 @@ Lexer.prototype.token = function(src, top) {
|
|
|
214
250
|
|
|
215
251
|
// table no leading pipe (gfm)
|
|
216
252
|
if (top && (cap = this.rules.nptable.exec(src))) {
|
|
217
|
-
src = src.substring(cap[0].length);
|
|
218
|
-
|
|
219
253
|
item = {
|
|
220
254
|
type: 'table',
|
|
221
|
-
header: cap[1].replace(/^ *| *\| *$/g, '')
|
|
255
|
+
header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
|
|
222
256
|
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
|
|
223
|
-
cells: cap[3].replace(/\n$/, '').split('\n')
|
|
257
|
+
cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : []
|
|
224
258
|
};
|
|
225
259
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
item.align[i]
|
|
231
|
-
|
|
232
|
-
item.align[i]
|
|
233
|
-
|
|
234
|
-
item.align[i]
|
|
260
|
+
if (item.header.length === item.align.length) {
|
|
261
|
+
src = src.substring(cap[0].length);
|
|
262
|
+
|
|
263
|
+
for (i = 0; i < item.align.length; i++) {
|
|
264
|
+
if (/^ *-+: *$/.test(item.align[i])) {
|
|
265
|
+
item.align[i] = 'right';
|
|
266
|
+
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
|
267
|
+
item.align[i] = 'center';
|
|
268
|
+
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
|
269
|
+
item.align[i] = 'left';
|
|
270
|
+
} else {
|
|
271
|
+
item.align[i] = null;
|
|
272
|
+
}
|
|
235
273
|
}
|
|
236
|
-
}
|
|
237
274
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
275
|
+
for (i = 0; i < item.cells.length; i++) {
|
|
276
|
+
item.cells[i] = splitCells(item.cells[i], item.header.length);
|
|
277
|
+
}
|
|
241
278
|
|
|
242
|
-
|
|
279
|
+
this.tokens.push(item);
|
|
243
280
|
|
|
244
|
-
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
245
283
|
}
|
|
246
284
|
|
|
247
285
|
// hr
|
|
@@ -279,15 +317,21 @@ Lexer.prototype.token = function(src, top) {
|
|
|
279
317
|
if (cap = this.rules.list.exec(src)) {
|
|
280
318
|
src = src.substring(cap[0].length);
|
|
281
319
|
bull = cap[2];
|
|
320
|
+
isordered = bull.length > 1;
|
|
282
321
|
|
|
283
|
-
|
|
322
|
+
listStart = {
|
|
284
323
|
type: 'list_start',
|
|
285
|
-
ordered:
|
|
286
|
-
|
|
324
|
+
ordered: isordered,
|
|
325
|
+
start: isordered ? +bull : '',
|
|
326
|
+
loose: false
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
this.tokens.push(listStart);
|
|
287
330
|
|
|
288
331
|
// Get each top-level item.
|
|
289
332
|
cap = cap[0].match(this.rules.item);
|
|
290
333
|
|
|
334
|
+
listItems = [];
|
|
291
335
|
next = false;
|
|
292
336
|
l = cap.length;
|
|
293
337
|
i = 0;
|
|
@@ -328,11 +372,27 @@ Lexer.prototype.token = function(src, top) {
|
|
|
328
372
|
if (!loose) loose = next;
|
|
329
373
|
}
|
|
330
374
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
375
|
+
if (loose) {
|
|
376
|
+
listStart.loose = true;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Check for task list items
|
|
380
|
+
istask = /^\[[ xX]\] /.test(item);
|
|
381
|
+
ischecked = undefined;
|
|
382
|
+
if (istask) {
|
|
383
|
+
ischecked = item[1] !== ' ';
|
|
384
|
+
item = item.replace(/^\[[ xX]\] +/, '');
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
t = {
|
|
388
|
+
type: 'list_item_start',
|
|
389
|
+
task: istask,
|
|
390
|
+
checked: ischecked,
|
|
391
|
+
loose: loose
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
listItems.push(t);
|
|
395
|
+
this.tokens.push(t);
|
|
336
396
|
|
|
337
397
|
// Recurse.
|
|
338
398
|
this.token(item, false);
|
|
@@ -342,6 +402,14 @@ Lexer.prototype.token = function(src, top) {
|
|
|
342
402
|
});
|
|
343
403
|
}
|
|
344
404
|
|
|
405
|
+
if (listStart.loose) {
|
|
406
|
+
l = listItems.length;
|
|
407
|
+
i = 0;
|
|
408
|
+
for (; i < l; i++) {
|
|
409
|
+
listItems[i].loose = true;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
345
413
|
this.tokens.push({
|
|
346
414
|
type: 'list_end'
|
|
347
415
|
});
|
|
@@ -367,7 +435,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
367
435
|
if (top && (cap = this.rules.def.exec(src))) {
|
|
368
436
|
src = src.substring(cap[0].length);
|
|
369
437
|
if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1);
|
|
370
|
-
tag = cap[1].toLowerCase();
|
|
438
|
+
tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
|
|
371
439
|
if (!this.tokens.links[tag]) {
|
|
372
440
|
this.tokens.links[tag] = {
|
|
373
441
|
href: cap[2],
|
|
@@ -379,36 +447,38 @@ Lexer.prototype.token = function(src, top) {
|
|
|
379
447
|
|
|
380
448
|
// table (gfm)
|
|
381
449
|
if (top && (cap = this.rules.table.exec(src))) {
|
|
382
|
-
src = src.substring(cap[0].length);
|
|
383
|
-
|
|
384
450
|
item = {
|
|
385
451
|
type: 'table',
|
|
386
|
-
header: cap[1].replace(/^ *| *\| *$/g, '')
|
|
452
|
+
header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
|
|
387
453
|
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
|
|
388
|
-
cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
|
|
454
|
+
cells: cap[3] ? cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') : []
|
|
389
455
|
};
|
|
390
456
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
item.align[i]
|
|
396
|
-
|
|
397
|
-
item.align[i]
|
|
398
|
-
|
|
399
|
-
item.align[i]
|
|
457
|
+
if (item.header.length === item.align.length) {
|
|
458
|
+
src = src.substring(cap[0].length);
|
|
459
|
+
|
|
460
|
+
for (i = 0; i < item.align.length; i++) {
|
|
461
|
+
if (/^ *-+: *$/.test(item.align[i])) {
|
|
462
|
+
item.align[i] = 'right';
|
|
463
|
+
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
|
464
|
+
item.align[i] = 'center';
|
|
465
|
+
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
|
466
|
+
item.align[i] = 'left';
|
|
467
|
+
} else {
|
|
468
|
+
item.align[i] = null;
|
|
469
|
+
}
|
|
400
470
|
}
|
|
401
|
-
}
|
|
402
471
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
472
|
+
for (i = 0; i < item.cells.length; i++) {
|
|
473
|
+
item.cells[i] = splitCells(
|
|
474
|
+
item.cells[i].replace(/^ *\| *| *\| *$/g, ''),
|
|
475
|
+
item.header.length);
|
|
476
|
+
}
|
|
408
477
|
|
|
409
|
-
|
|
478
|
+
this.tokens.push(item);
|
|
410
479
|
|
|
411
|
-
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
412
482
|
}
|
|
413
483
|
|
|
414
484
|
// lheading
|
|
@@ -458,39 +528,54 @@ Lexer.prototype.token = function(src, top) {
|
|
|
458
528
|
*/
|
|
459
529
|
|
|
460
530
|
var inline = {
|
|
461
|
-
escape: /^\\([
|
|
531
|
+
escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
|
|
462
532
|
autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
|
|
463
533
|
url: noop,
|
|
464
|
-
tag:
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
534
|
+
tag: '^comment'
|
|
535
|
+
+ '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
|
|
536
|
+
+ '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
|
|
537
|
+
+ '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
|
|
538
|
+
+ '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
|
|
539
|
+
+ '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', // CDATA section
|
|
540
|
+
link: /^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,
|
|
541
|
+
reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
|
|
542
|
+
nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
|
|
543
|
+
strong: /^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)|^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)/,
|
|
544
|
+
em: /^_([^\s_])_(?!_)|^\*([^\s*"<\[])\*(?!\*)|^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s"<\[][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*"<\[][\s\S]*?[^\s])\*(?!\*)/,
|
|
470
545
|
code: /^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,
|
|
471
|
-
br: /^ {2,}\n(?!\s*$)/,
|
|
546
|
+
br: /^( {2,}|\\)\n(?!\s*$)/,
|
|
472
547
|
del: noop,
|
|
473
548
|
text: /^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/
|
|
474
549
|
};
|
|
475
550
|
|
|
551
|
+
inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
|
|
552
|
+
|
|
476
553
|
inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
|
|
477
554
|
inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
|
|
478
|
-
|
|
479
555
|
inline.autolink = edit(inline.autolink)
|
|
480
556
|
.replace('scheme', inline._scheme)
|
|
481
557
|
.replace('email', inline._email)
|
|
482
|
-
.getRegex()
|
|
558
|
+
.getRegex();
|
|
483
559
|
|
|
484
|
-
inline.
|
|
485
|
-
|
|
560
|
+
inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
|
|
561
|
+
|
|
562
|
+
inline.tag = edit(inline.tag)
|
|
563
|
+
.replace('comment', block._comment)
|
|
564
|
+
.replace('attribute', inline._attribute)
|
|
565
|
+
.getRegex();
|
|
566
|
+
|
|
567
|
+
inline._label = /(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/;
|
|
568
|
+
inline._href = /\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f\\]*\)|[^\s\x00-\x1f()\\])*?)/;
|
|
569
|
+
inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
|
|
486
570
|
|
|
487
571
|
inline.link = edit(inline.link)
|
|
488
|
-
.replace('
|
|
572
|
+
.replace('label', inline._label)
|
|
489
573
|
.replace('href', inline._href)
|
|
574
|
+
.replace('title', inline._title)
|
|
490
575
|
.getRegex();
|
|
491
576
|
|
|
492
577
|
inline.reflink = edit(inline.reflink)
|
|
493
|
-
.replace('
|
|
578
|
+
.replace('label', inline._label)
|
|
494
579
|
.getRegex();
|
|
495
580
|
|
|
496
581
|
/**
|
|
@@ -505,7 +590,13 @@ inline.normal = merge({}, inline);
|
|
|
505
590
|
|
|
506
591
|
inline.pedantic = merge({}, inline.normal, {
|
|
507
592
|
strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
|
508
|
-
em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)
|
|
593
|
+
em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
|
|
594
|
+
link: edit(/^!?\[(label)\]\((.*?)\)/)
|
|
595
|
+
.replace('label', inline._label)
|
|
596
|
+
.getRegex(),
|
|
597
|
+
reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
|
|
598
|
+
.replace('label', inline._label)
|
|
599
|
+
.getRegex()
|
|
509
600
|
});
|
|
510
601
|
|
|
511
602
|
/**
|
|
@@ -518,7 +609,7 @@ inline.gfm = merge({}, inline.normal, {
|
|
|
518
609
|
.replace('email', inline._email)
|
|
519
610
|
.getRegex(),
|
|
520
611
|
_backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
|
|
521
|
-
del:
|
|
612
|
+
del: /^~+(?=\S)([\s\S]*?\S)~+/,
|
|
522
613
|
text: edit(inline.text)
|
|
523
614
|
.replace(']|', '~]|')
|
|
524
615
|
.replace('|', '|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&\'*+/=?^_`{\\|}~-]+@|')
|
|
@@ -549,14 +640,14 @@ function InlineLexer(links, options) {
|
|
|
549
640
|
throw new Error('Tokens array requires a `links` property.');
|
|
550
641
|
}
|
|
551
642
|
|
|
552
|
-
if (this.options.
|
|
643
|
+
if (this.options.pedantic) {
|
|
644
|
+
this.rules = inline.pedantic;
|
|
645
|
+
} else if (this.options.gfm) {
|
|
553
646
|
if (this.options.breaks) {
|
|
554
647
|
this.rules = inline.breaks;
|
|
555
648
|
} else {
|
|
556
649
|
this.rules = inline.gfm;
|
|
557
650
|
}
|
|
558
|
-
} else if (this.options.pedantic) {
|
|
559
|
-
this.rules = inline.pedantic;
|
|
560
651
|
}
|
|
561
652
|
}
|
|
562
653
|
|
|
@@ -584,7 +675,9 @@ InlineLexer.prototype.output = function(src) {
|
|
|
584
675
|
link,
|
|
585
676
|
text,
|
|
586
677
|
href,
|
|
587
|
-
|
|
678
|
+
title,
|
|
679
|
+
cap,
|
|
680
|
+
prevCapZero;
|
|
588
681
|
|
|
589
682
|
while (src) {
|
|
590
683
|
// escape
|
|
@@ -610,7 +703,10 @@ InlineLexer.prototype.output = function(src) {
|
|
|
610
703
|
|
|
611
704
|
// url (gfm)
|
|
612
705
|
if (!this.inLink && (cap = this.rules.url.exec(src))) {
|
|
613
|
-
|
|
706
|
+
do {
|
|
707
|
+
prevCapZero = cap[0];
|
|
708
|
+
cap[0] = this.rules._backpedal.exec(cap[0])[0];
|
|
709
|
+
} while (prevCapZero !== cap[0]);
|
|
614
710
|
src = src.substring(cap[0].length);
|
|
615
711
|
if (cap[2] === '@') {
|
|
616
712
|
text = escape(cap[0]);
|
|
@@ -647,9 +743,23 @@ InlineLexer.prototype.output = function(src) {
|
|
|
647
743
|
if (cap = this.rules.link.exec(src)) {
|
|
648
744
|
src = src.substring(cap[0].length);
|
|
649
745
|
this.inLink = true;
|
|
746
|
+
href = cap[2];
|
|
747
|
+
if (this.options.pedantic) {
|
|
748
|
+
link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
|
|
749
|
+
|
|
750
|
+
if (link) {
|
|
751
|
+
href = link[1];
|
|
752
|
+
title = link[3];
|
|
753
|
+
} else {
|
|
754
|
+
title = '';
|
|
755
|
+
}
|
|
756
|
+
} else {
|
|
757
|
+
title = cap[3] ? cap[3].slice(1, -1) : '';
|
|
758
|
+
}
|
|
759
|
+
href = href.trim().replace(/^<([\s\S]*)>$/, '$1');
|
|
650
760
|
out += this.outputLink(cap, {
|
|
651
|
-
href:
|
|
652
|
-
title:
|
|
761
|
+
href: InlineLexer.escapes(href),
|
|
762
|
+
title: InlineLexer.escapes(title)
|
|
653
763
|
});
|
|
654
764
|
this.inLink = false;
|
|
655
765
|
continue;
|
|
@@ -675,14 +785,14 @@ InlineLexer.prototype.output = function(src) {
|
|
|
675
785
|
// strong
|
|
676
786
|
if (cap = this.rules.strong.exec(src)) {
|
|
677
787
|
src = src.substring(cap[0].length);
|
|
678
|
-
out += this.renderer.strong(this.output(cap[2] || cap[1]));
|
|
788
|
+
out += this.renderer.strong(this.output(cap[4] || cap[3] || cap[2] || cap[1]));
|
|
679
789
|
continue;
|
|
680
790
|
}
|
|
681
791
|
|
|
682
792
|
// em
|
|
683
793
|
if (cap = this.rules.em.exec(src)) {
|
|
684
794
|
src = src.substring(cap[0].length);
|
|
685
|
-
out += this.renderer.em(this.output(cap[2] || cap[1]));
|
|
795
|
+
out += this.renderer.em(this.output(cap[6] || cap[5] || cap[4] || cap[3] || cap[2] || cap[1]));
|
|
686
796
|
continue;
|
|
687
797
|
}
|
|
688
798
|
|
|
@@ -722,12 +832,16 @@ InlineLexer.prototype.output = function(src) {
|
|
|
722
832
|
return out;
|
|
723
833
|
};
|
|
724
834
|
|
|
835
|
+
InlineLexer.escapes = function(text) {
|
|
836
|
+
return text ? text.replace(InlineLexer.rules._escapes, '$1') : text;
|
|
837
|
+
}
|
|
838
|
+
|
|
725
839
|
/**
|
|
726
840
|
* Compile Link
|
|
727
841
|
*/
|
|
728
842
|
|
|
729
843
|
InlineLexer.prototype.outputLink = function(cap, link) {
|
|
730
|
-
var href =
|
|
844
|
+
var href = link.href,
|
|
731
845
|
title = link.title ? escape(link.title) : null;
|
|
732
846
|
|
|
733
847
|
return cap[0].charAt(0) !== '!'
|
|
@@ -785,7 +899,7 @@ InlineLexer.prototype.mangle = function(text) {
|
|
|
785
899
|
*/
|
|
786
900
|
|
|
787
901
|
function Renderer(options) {
|
|
788
|
-
this.options = options ||
|
|
902
|
+
this.options = options || marked.defaults;
|
|
789
903
|
}
|
|
790
904
|
|
|
791
905
|
Renderer.prototype.code = function(code, lang, escaped) {
|
|
@@ -800,7 +914,7 @@ Renderer.prototype.code = function(code, lang, escaped) {
|
|
|
800
914
|
if (!lang) {
|
|
801
915
|
return '<pre><code>'
|
|
802
916
|
+ (escaped ? code : escape(code, true))
|
|
803
|
-
+ '
|
|
917
|
+
+ '</code></pre>';
|
|
804
918
|
}
|
|
805
919
|
|
|
806
920
|
return '<pre><code class="'
|
|
@@ -808,7 +922,7 @@ Renderer.prototype.code = function(code, lang, escaped) {
|
|
|
808
922
|
+ escape(lang, true)
|
|
809
923
|
+ '">'
|
|
810
924
|
+ (escaped ? code : escape(code, true))
|
|
811
|
-
+ '
|
|
925
|
+
+ '</code></pre>\n';
|
|
812
926
|
};
|
|
813
927
|
|
|
814
928
|
Renderer.prototype.blockquote = function(quote) {
|
|
@@ -820,43 +934,56 @@ Renderer.prototype.html = function(html) {
|
|
|
820
934
|
};
|
|
821
935
|
|
|
822
936
|
Renderer.prototype.heading = function(text, level, raw) {
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
937
|
+
if (this.options.headerIds) {
|
|
938
|
+
return '<h'
|
|
939
|
+
+ level
|
|
940
|
+
+ ' id="'
|
|
941
|
+
+ this.options.headerPrefix
|
|
942
|
+
+ raw.toLowerCase().replace(/[^\w]+/g, '-')
|
|
943
|
+
+ '">'
|
|
944
|
+
+ text
|
|
945
|
+
+ '</h'
|
|
946
|
+
+ level
|
|
947
|
+
+ '>\n';
|
|
948
|
+
}
|
|
949
|
+
// ignore IDs
|
|
950
|
+
return '<h' + level + '>' + text + '</h' + level + '>\n';
|
|
833
951
|
};
|
|
834
952
|
|
|
835
953
|
Renderer.prototype.hr = function() {
|
|
836
954
|
return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
|
|
837
955
|
};
|
|
838
956
|
|
|
839
|
-
Renderer.prototype.list = function(body, ordered) {
|
|
840
|
-
var type = ordered ? 'ol' : 'ul'
|
|
841
|
-
|
|
957
|
+
Renderer.prototype.list = function(body, ordered, start) {
|
|
958
|
+
var type = ordered ? 'ol' : 'ul',
|
|
959
|
+
startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
|
|
960
|
+
return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
|
|
842
961
|
};
|
|
843
962
|
|
|
844
963
|
Renderer.prototype.listitem = function(text) {
|
|
845
964
|
return '<li>' + text + '</li>\n';
|
|
846
965
|
};
|
|
847
966
|
|
|
967
|
+
Renderer.prototype.checkbox = function(checked) {
|
|
968
|
+
return '<input '
|
|
969
|
+
+ (checked ? 'checked="" ' : '')
|
|
970
|
+
+ 'disabled="" type="checkbox"'
|
|
971
|
+
+ (this.options.xhtml ? ' /' : '')
|
|
972
|
+
+ '> ';
|
|
973
|
+
}
|
|
974
|
+
|
|
848
975
|
Renderer.prototype.paragraph = function(text) {
|
|
849
976
|
return '<p>' + text + '</p>\n';
|
|
850
977
|
};
|
|
851
978
|
|
|
852
979
|
Renderer.prototype.table = function(header, body) {
|
|
980
|
+
if (body) body = '<tbody>' + body + '</tbody>';
|
|
981
|
+
|
|
853
982
|
return '<table>\n'
|
|
854
983
|
+ '<thead>\n'
|
|
855
984
|
+ header
|
|
856
985
|
+ '</thead>\n'
|
|
857
|
-
+ '<tbody>\n'
|
|
858
986
|
+ body
|
|
859
|
-
+ '</tbody>\n'
|
|
860
987
|
+ '</table>\n';
|
|
861
988
|
};
|
|
862
989
|
|
|
@@ -867,7 +994,7 @@ Renderer.prototype.tablerow = function(content) {
|
|
|
867
994
|
Renderer.prototype.tablecell = function(content, flags) {
|
|
868
995
|
var type = flags.header ? 'th' : 'td';
|
|
869
996
|
var tag = flags.align
|
|
870
|
-
? '<' + type + '
|
|
997
|
+
? '<' + type + ' align="' + flags.align + '">'
|
|
871
998
|
: '<' + type + '>';
|
|
872
999
|
return tag + content + '</' + type + '>\n';
|
|
873
1000
|
};
|
|
@@ -909,7 +1036,12 @@ Renderer.prototype.link = function(href, title, text) {
|
|
|
909
1036
|
if (this.options.baseUrl && !originIndependentUrl.test(href)) {
|
|
910
1037
|
href = resolveUrl(this.options.baseUrl, href);
|
|
911
1038
|
}
|
|
912
|
-
|
|
1039
|
+
try {
|
|
1040
|
+
href = encodeURI(href).replace(/%25/g, '%');
|
|
1041
|
+
} catch (e) {
|
|
1042
|
+
return text;
|
|
1043
|
+
}
|
|
1044
|
+
var out = '<a href="' + escape(href) + '"';
|
|
913
1045
|
if (title) {
|
|
914
1046
|
out += ' title="' + title + '"';
|
|
915
1047
|
}
|
|
@@ -1099,39 +1231,34 @@ Parser.prototype.tok = function() {
|
|
|
1099
1231
|
}
|
|
1100
1232
|
case 'list_start': {
|
|
1101
1233
|
body = '';
|
|
1102
|
-
var ordered = this.token.ordered
|
|
1234
|
+
var ordered = this.token.ordered,
|
|
1235
|
+
start = this.token.start;
|
|
1103
1236
|
|
|
1104
1237
|
while (this.next().type !== 'list_end') {
|
|
1105
1238
|
body += this.tok();
|
|
1106
1239
|
}
|
|
1107
1240
|
|
|
1108
|
-
return this.renderer.list(body, ordered);
|
|
1241
|
+
return this.renderer.list(body, ordered, start);
|
|
1109
1242
|
}
|
|
1110
1243
|
case 'list_item_start': {
|
|
1111
1244
|
body = '';
|
|
1245
|
+
var loose = this.token.loose;
|
|
1112
1246
|
|
|
1113
|
-
|
|
1114
|
-
body += this.token.
|
|
1115
|
-
? this.parseText()
|
|
1116
|
-
: this.tok();
|
|
1247
|
+
if (this.token.task) {
|
|
1248
|
+
body += this.renderer.checkbox(this.token.checked);
|
|
1117
1249
|
}
|
|
1118
1250
|
|
|
1119
|
-
return this.renderer.listitem(body);
|
|
1120
|
-
}
|
|
1121
|
-
case 'loose_item_start': {
|
|
1122
|
-
body = '';
|
|
1123
|
-
|
|
1124
1251
|
while (this.next().type !== 'list_item_end') {
|
|
1125
|
-
body += this.
|
|
1252
|
+
body += !loose && this.token.type === 'text'
|
|
1253
|
+
? this.parseText()
|
|
1254
|
+
: this.tok();
|
|
1126
1255
|
}
|
|
1127
1256
|
|
|
1128
1257
|
return this.renderer.listitem(body);
|
|
1129
1258
|
}
|
|
1130
1259
|
case 'html': {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
: this.token.text;
|
|
1134
|
-
return this.renderer.html(html);
|
|
1260
|
+
// TODO parse inline content if parameter markdown=1
|
|
1261
|
+
return this.renderer.html(this.token.text);
|
|
1135
1262
|
}
|
|
1136
1263
|
case 'paragraph': {
|
|
1137
1264
|
return this.renderer.paragraph(this.inline.output(this.token.text));
|
|
@@ -1170,7 +1297,7 @@ function unescape(html) {
|
|
|
1170
1297
|
}
|
|
1171
1298
|
|
|
1172
1299
|
function edit(regex, opt) {
|
|
1173
|
-
regex = regex.source;
|
|
1300
|
+
regex = regex.source || regex;
|
|
1174
1301
|
opt = opt || '';
|
|
1175
1302
|
return {
|
|
1176
1303
|
replace: function(name, val) {
|
|
@@ -1193,7 +1320,7 @@ function resolveUrl(base, href) {
|
|
|
1193
1320
|
if (/^[^:]+:\/*[^/]*$/.test(base)) {
|
|
1194
1321
|
baseUrls[' ' + base] = base + '/';
|
|
1195
1322
|
} else {
|
|
1196
|
-
baseUrls[' ' + base] = base
|
|
1323
|
+
baseUrls[' ' + base] = rtrim(base, '/', true);
|
|
1197
1324
|
}
|
|
1198
1325
|
}
|
|
1199
1326
|
base = baseUrls[' ' + base];
|
|
@@ -1229,6 +1356,64 @@ function merge(obj) {
|
|
|
1229
1356
|
return obj;
|
|
1230
1357
|
}
|
|
1231
1358
|
|
|
1359
|
+
function splitCells(tableRow, count) {
|
|
1360
|
+
// ensure that every cell-delimiting pipe has a space
|
|
1361
|
+
// before it to distinguish it from an escaped pipe
|
|
1362
|
+
var row = tableRow.replace(/\|/g, function (match, offset, str) {
|
|
1363
|
+
var escaped = false,
|
|
1364
|
+
curr = offset;
|
|
1365
|
+
while (--curr >= 0 && str[curr] === '\\') escaped = !escaped;
|
|
1366
|
+
if (escaped) {
|
|
1367
|
+
// odd number of slashes means | is escaped
|
|
1368
|
+
// so we leave it alone
|
|
1369
|
+
return '|';
|
|
1370
|
+
} else {
|
|
1371
|
+
// add space before unescaped |
|
|
1372
|
+
return ' |';
|
|
1373
|
+
}
|
|
1374
|
+
}),
|
|
1375
|
+
cells = row.split(/ \|/),
|
|
1376
|
+
i = 0;
|
|
1377
|
+
|
|
1378
|
+
if (cells.length > count) {
|
|
1379
|
+
cells.splice(count);
|
|
1380
|
+
} else {
|
|
1381
|
+
while (cells.length < count) cells.push('');
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
for (; i < cells.length; i++) {
|
|
1385
|
+
// leading or trailing whitespace is ignored per the gfm spec
|
|
1386
|
+
cells[i] = cells[i].trim().replace(/\\\|/g, '|');
|
|
1387
|
+
}
|
|
1388
|
+
return cells;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
|
|
1392
|
+
// /c*$/ is vulnerable to REDOS.
|
|
1393
|
+
// invert: Remove suffix of non-c chars instead. Default falsey.
|
|
1394
|
+
function rtrim(str, c, invert) {
|
|
1395
|
+
if (str.length === 0) {
|
|
1396
|
+
return '';
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
// Length of suffix matching the invert condition.
|
|
1400
|
+
var suffLen = 0;
|
|
1401
|
+
|
|
1402
|
+
// Step left until we fail to match the invert condition.
|
|
1403
|
+
while (suffLen < str.length) {
|
|
1404
|
+
var currChar = str.charAt(str.length - suffLen - 1);
|
|
1405
|
+
if (currChar === c && !invert) {
|
|
1406
|
+
suffLen++;
|
|
1407
|
+
} else if (currChar !== c && invert) {
|
|
1408
|
+
suffLen++;
|
|
1409
|
+
} else {
|
|
1410
|
+
break;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
return str.substr(0, str.length - suffLen);
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1232
1417
|
/**
|
|
1233
1418
|
* Marked
|
|
1234
1419
|
*/
|
|
@@ -1316,7 +1501,7 @@ function marked(src, opt, callback) {
|
|
|
1316
1501
|
if (opt) opt = merge({}, marked.defaults, opt);
|
|
1317
1502
|
return Parser.parse(Lexer.lex(src, opt), opt);
|
|
1318
1503
|
} catch (e) {
|
|
1319
|
-
e.message += '\nPlease report this to https://github.com/
|
|
1504
|
+
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
|
1320
1505
|
if ((opt || marked.defaults).silent) {
|
|
1321
1506
|
return '<p>An error occurred:</p><pre>'
|
|
1322
1507
|
+ escape(e.message + '', true)
|
|
@@ -1336,24 +1521,29 @@ marked.setOptions = function(opt) {
|
|
|
1336
1521
|
return marked;
|
|
1337
1522
|
};
|
|
1338
1523
|
|
|
1339
|
-
marked.
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1524
|
+
marked.getDefaults = function () {
|
|
1525
|
+
return {
|
|
1526
|
+
baseUrl: null,
|
|
1527
|
+
breaks: false,
|
|
1528
|
+
gfm: true,
|
|
1529
|
+
headerIds: true,
|
|
1530
|
+
headerPrefix: '',
|
|
1531
|
+
highlight: null,
|
|
1532
|
+
langPrefix: 'language-',
|
|
1533
|
+
mangle: true,
|
|
1534
|
+
pedantic: false,
|
|
1535
|
+
renderer: new Renderer(),
|
|
1536
|
+
sanitize: false,
|
|
1537
|
+
sanitizer: null,
|
|
1538
|
+
silent: false,
|
|
1539
|
+
smartLists: false,
|
|
1540
|
+
smartypants: false,
|
|
1541
|
+
tables: true,
|
|
1542
|
+
xhtml: false
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
marked.defaults = marked.getDefaults();
|
|
1357
1547
|
|
|
1358
1548
|
/**
|
|
1359
1549
|
* Expose
|