marked 0.8.2 → 1.0.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/README.md +1 -1
- package/lib/marked.esm.js +1205 -808
- package/lib/marked.js +1364 -810
- package/marked.min.js +1 -1
- package/package.json +8 -8
- package/src/Lexer.js +304 -284
- package/src/Parser.js +206 -157
- package/src/Renderer.js +20 -20
- package/src/Slugger.js +1 -1
- package/src/Tokenizer.js +586 -0
- package/src/defaults.js +1 -0
- package/src/marked.js +39 -3
- package/src/rules.js +2 -2
- package/src/InlineLexer.js +0 -293
package/src/Parser.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
const Renderer = require('./Renderer.js');
|
|
2
|
-
const Slugger = require('./Slugger.js');
|
|
3
|
-
const InlineLexer = require('./InlineLexer.js');
|
|
4
2
|
const TextRenderer = require('./TextRenderer.js');
|
|
3
|
+
const Slugger = require('./Slugger.js');
|
|
5
4
|
const { defaults } = require('./defaults.js');
|
|
6
5
|
const {
|
|
7
|
-
merge,
|
|
8
6
|
unescape
|
|
9
7
|
} = require('./helpers.js');
|
|
10
8
|
|
|
@@ -13,12 +11,11 @@ const {
|
|
|
13
11
|
*/
|
|
14
12
|
module.exports = class Parser {
|
|
15
13
|
constructor(options) {
|
|
16
|
-
this.tokens = [];
|
|
17
|
-
this.token = null;
|
|
18
14
|
this.options = options || defaults;
|
|
19
15
|
this.options.renderer = this.options.renderer || new Renderer();
|
|
20
16
|
this.renderer = this.options.renderer;
|
|
21
17
|
this.renderer.options = this.options;
|
|
18
|
+
this.textRenderer = new TextRenderer();
|
|
22
19
|
this.slugger = new Slugger();
|
|
23
20
|
}
|
|
24
21
|
|
|
@@ -28,179 +25,231 @@ module.exports = class Parser {
|
|
|
28
25
|
static parse(tokens, options) {
|
|
29
26
|
const parser = new Parser(options);
|
|
30
27
|
return parser.parse(tokens);
|
|
31
|
-
}
|
|
28
|
+
}
|
|
32
29
|
|
|
33
30
|
/**
|
|
34
31
|
* Parse Loop
|
|
35
32
|
*/
|
|
36
|
-
parse(tokens) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
tok() {
|
|
85
|
-
let body = '';
|
|
86
|
-
switch (this.token.type) {
|
|
87
|
-
case 'space': {
|
|
88
|
-
return '';
|
|
89
|
-
}
|
|
90
|
-
case 'hr': {
|
|
91
|
-
return this.renderer.hr();
|
|
92
|
-
}
|
|
93
|
-
case 'heading': {
|
|
94
|
-
return this.renderer.heading(
|
|
95
|
-
this.inline.output(this.token.text),
|
|
96
|
-
this.token.depth,
|
|
97
|
-
unescape(this.inlineText.output(this.token.text)),
|
|
98
|
-
this.slugger);
|
|
99
|
-
}
|
|
100
|
-
case 'code': {
|
|
101
|
-
return this.renderer.code(this.token.text,
|
|
102
|
-
this.token.lang,
|
|
103
|
-
this.token.escaped);
|
|
104
|
-
}
|
|
105
|
-
case 'table': {
|
|
106
|
-
let header = '',
|
|
107
|
-
i,
|
|
108
|
-
row,
|
|
109
|
-
cell,
|
|
110
|
-
j;
|
|
111
|
-
|
|
112
|
-
// header
|
|
113
|
-
cell = '';
|
|
114
|
-
for (i = 0; i < this.token.header.length; i++) {
|
|
115
|
-
cell += this.renderer.tablecell(
|
|
116
|
-
this.inline.output(this.token.header[i]),
|
|
117
|
-
{ header: true, align: this.token.align[i] }
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
header += this.renderer.tablerow(cell);
|
|
121
|
-
|
|
122
|
-
for (i = 0; i < this.token.cells.length; i++) {
|
|
123
|
-
row = this.token.cells[i];
|
|
33
|
+
parse(tokens, top = true) {
|
|
34
|
+
let out = '',
|
|
35
|
+
i,
|
|
36
|
+
j,
|
|
37
|
+
k,
|
|
38
|
+
l2,
|
|
39
|
+
l3,
|
|
40
|
+
row,
|
|
41
|
+
cell,
|
|
42
|
+
header,
|
|
43
|
+
body,
|
|
44
|
+
token,
|
|
45
|
+
ordered,
|
|
46
|
+
start,
|
|
47
|
+
loose,
|
|
48
|
+
itemBody,
|
|
49
|
+
item,
|
|
50
|
+
checked,
|
|
51
|
+
task,
|
|
52
|
+
checkbox;
|
|
53
|
+
|
|
54
|
+
const l = tokens.length;
|
|
55
|
+
for (i = 0; i < l; i++) {
|
|
56
|
+
token = tokens[i];
|
|
57
|
+
switch (token.type) {
|
|
58
|
+
case 'space': {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
case 'hr': {
|
|
62
|
+
out += this.renderer.hr();
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
case 'heading': {
|
|
66
|
+
out += this.renderer.heading(
|
|
67
|
+
this.parseInline(token.tokens),
|
|
68
|
+
token.depth,
|
|
69
|
+
unescape(this.parseInline(token.tokens, this.textRenderer)),
|
|
70
|
+
this.slugger);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
case 'code': {
|
|
74
|
+
out += this.renderer.code(token.text,
|
|
75
|
+
token.lang,
|
|
76
|
+
token.escaped);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
case 'table': {
|
|
80
|
+
header = '';
|
|
124
81
|
|
|
82
|
+
// header
|
|
125
83
|
cell = '';
|
|
126
|
-
|
|
84
|
+
l2 = token.header.length;
|
|
85
|
+
for (j = 0; j < l2; j++) {
|
|
127
86
|
cell += this.renderer.tablecell(
|
|
128
|
-
this.
|
|
129
|
-
{ header:
|
|
87
|
+
this.parseInline(token.tokens.header[j]),
|
|
88
|
+
{ header: true, align: token.align[j] }
|
|
130
89
|
);
|
|
131
90
|
}
|
|
91
|
+
header += this.renderer.tablerow(cell);
|
|
92
|
+
|
|
93
|
+
body = '';
|
|
94
|
+
l2 = token.cells.length;
|
|
95
|
+
for (j = 0; j < l2; j++) {
|
|
96
|
+
row = token.tokens.cells[j];
|
|
97
|
+
|
|
98
|
+
cell = '';
|
|
99
|
+
l3 = row.length;
|
|
100
|
+
for (k = 0; k < l3; k++) {
|
|
101
|
+
cell += this.renderer.tablecell(
|
|
102
|
+
this.parseInline(row[k]),
|
|
103
|
+
{ header: false, align: token.align[k] }
|
|
104
|
+
);
|
|
105
|
+
}
|
|
132
106
|
|
|
133
|
-
|
|
107
|
+
body += this.renderer.tablerow(cell);
|
|
108
|
+
}
|
|
109
|
+
out += this.renderer.table(header, body);
|
|
110
|
+
continue;
|
|
134
111
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
while (this.next().type !== 'blockquote_end') {
|
|
141
|
-
body += this.tok();
|
|
112
|
+
case 'blockquote': {
|
|
113
|
+
body = this.parse(token.tokens);
|
|
114
|
+
out += this.renderer.blockquote(body);
|
|
115
|
+
continue;
|
|
142
116
|
}
|
|
117
|
+
case 'list': {
|
|
118
|
+
ordered = token.ordered;
|
|
119
|
+
start = token.start;
|
|
120
|
+
loose = token.loose;
|
|
121
|
+
l2 = token.items.length;
|
|
122
|
+
|
|
123
|
+
body = '';
|
|
124
|
+
for (j = 0; j < l2; j++) {
|
|
125
|
+
item = token.items[j];
|
|
126
|
+
checked = item.checked;
|
|
127
|
+
task = item.task;
|
|
128
|
+
|
|
129
|
+
itemBody = '';
|
|
130
|
+
if (item.task) {
|
|
131
|
+
checkbox = this.renderer.checkbox(checked);
|
|
132
|
+
if (loose) {
|
|
133
|
+
if (item.tokens[0].type === 'text') {
|
|
134
|
+
item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
|
|
135
|
+
if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
|
|
136
|
+
item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
item.tokens.unshift({
|
|
140
|
+
type: 'text',
|
|
141
|
+
text: checkbox
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
itemBody += checkbox;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
143
148
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
body = '';
|
|
148
|
-
const ordered = this.token.ordered,
|
|
149
|
-
start = this.token.start;
|
|
149
|
+
itemBody += this.parse(item.tokens, loose);
|
|
150
|
+
body += this.renderer.listitem(itemBody, task, checked);
|
|
151
|
+
}
|
|
150
152
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
+
out += this.renderer.list(body, ordered, start);
|
|
154
|
+
continue;
|
|
153
155
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
156
|
+
case 'html': {
|
|
157
|
+
// TODO parse inline content if parameter markdown=1
|
|
158
|
+
out += this.renderer.html(token.text);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
case 'paragraph': {
|
|
162
|
+
out += this.renderer.paragraph(this.parseInline(token.tokens));
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
case 'text': {
|
|
166
|
+
body = token.tokens ? this.parseInline(token.tokens) : token.text;
|
|
167
|
+
while (i + 1 < l && tokens[i + 1].type === 'text') {
|
|
168
|
+
token = tokens[++i];
|
|
169
|
+
body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
|
|
170
|
+
}
|
|
171
|
+
out += top ? this.renderer.paragraph(body) : body;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
default: {
|
|
175
|
+
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
176
|
+
if (this.options.silent) {
|
|
177
|
+
console.error(errMsg);
|
|
178
|
+
return;
|
|
174
179
|
} else {
|
|
175
|
-
|
|
180
|
+
throw new Error(errMsg);
|
|
176
181
|
}
|
|
177
182
|
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
178
185
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Parse Inline Tokens
|
|
191
|
+
*/
|
|
192
|
+
parseInline(tokens, renderer) {
|
|
193
|
+
renderer = renderer || this.renderer;
|
|
194
|
+
let out = '',
|
|
195
|
+
i,
|
|
196
|
+
token;
|
|
197
|
+
|
|
198
|
+
const l = tokens.length;
|
|
199
|
+
for (i = 0; i < l; i++) {
|
|
200
|
+
token = tokens[i];
|
|
201
|
+
switch (token.type) {
|
|
202
|
+
case 'escape': {
|
|
203
|
+
out += renderer.text(token.text);
|
|
204
|
+
break;
|
|
183
205
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
case 'html': {
|
|
207
|
+
out += renderer.html(token.text);
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
case 'link': {
|
|
211
|
+
out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
case 'image': {
|
|
215
|
+
out += renderer.image(token.href, token.title, token.text);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case 'strong': {
|
|
219
|
+
out += renderer.strong(this.parseInline(token.tokens, renderer));
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
case 'em': {
|
|
223
|
+
out += renderer.em(this.parseInline(token.tokens, renderer));
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
case 'codespan': {
|
|
227
|
+
out += renderer.codespan(token.text);
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case 'br': {
|
|
231
|
+
out += renderer.br();
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
case 'del': {
|
|
235
|
+
out += renderer.del(this.parseInline(token.tokens, renderer));
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
case 'text': {
|
|
239
|
+
out += renderer.text(token.text);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
default: {
|
|
243
|
+
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
244
|
+
if (this.options.silent) {
|
|
245
|
+
console.error(errMsg);
|
|
246
|
+
return;
|
|
247
|
+
} else {
|
|
248
|
+
throw new Error(errMsg);
|
|
249
|
+
}
|
|
202
250
|
}
|
|
203
251
|
}
|
|
204
252
|
}
|
|
205
|
-
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
206
255
|
};
|
package/src/Renderer.js
CHANGED
|
@@ -34,15 +34,15 @@ module.exports = class Renderer {
|
|
|
34
34
|
+ '">'
|
|
35
35
|
+ (escaped ? code : escape(code, true))
|
|
36
36
|
+ '</code></pre>\n';
|
|
37
|
-
}
|
|
37
|
+
}
|
|
38
38
|
|
|
39
39
|
blockquote(quote) {
|
|
40
40
|
return '<blockquote>\n' + quote + '</blockquote>\n';
|
|
41
|
-
}
|
|
41
|
+
}
|
|
42
42
|
|
|
43
43
|
html(html) {
|
|
44
44
|
return html;
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
|
|
47
47
|
heading(text, level, raw, slugger) {
|
|
48
48
|
if (this.options.headerIds) {
|
|
@@ -59,21 +59,21 @@ module.exports = class Renderer {
|
|
|
59
59
|
}
|
|
60
60
|
// ignore IDs
|
|
61
61
|
return '<h' + level + '>' + text + '</h' + level + '>\n';
|
|
62
|
-
}
|
|
62
|
+
}
|
|
63
63
|
|
|
64
64
|
hr() {
|
|
65
65
|
return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
|
|
66
|
-
}
|
|
66
|
+
}
|
|
67
67
|
|
|
68
68
|
list(body, ordered, start) {
|
|
69
69
|
const type = ordered ? 'ol' : 'ul',
|
|
70
70
|
startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
|
|
71
71
|
return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
|
|
72
|
-
}
|
|
72
|
+
}
|
|
73
73
|
|
|
74
74
|
listitem(text) {
|
|
75
75
|
return '<li>' + text + '</li>\n';
|
|
76
|
-
}
|
|
76
|
+
}
|
|
77
77
|
|
|
78
78
|
checkbox(checked) {
|
|
79
79
|
return '<input '
|
|
@@ -81,11 +81,11 @@ module.exports = class Renderer {
|
|
|
81
81
|
+ 'disabled="" type="checkbox"'
|
|
82
82
|
+ (this.options.xhtml ? ' /' : '')
|
|
83
83
|
+ '> ';
|
|
84
|
-
}
|
|
84
|
+
}
|
|
85
85
|
|
|
86
86
|
paragraph(text) {
|
|
87
87
|
return '<p>' + text + '</p>\n';
|
|
88
|
-
}
|
|
88
|
+
}
|
|
89
89
|
|
|
90
90
|
table(header, body) {
|
|
91
91
|
if (body) body = '<tbody>' + body + '</tbody>';
|
|
@@ -96,11 +96,11 @@ module.exports = class Renderer {
|
|
|
96
96
|
+ '</thead>\n'
|
|
97
97
|
+ body
|
|
98
98
|
+ '</table>\n';
|
|
99
|
-
}
|
|
99
|
+
}
|
|
100
100
|
|
|
101
101
|
tablerow(content) {
|
|
102
102
|
return '<tr>\n' + content + '</tr>\n';
|
|
103
|
-
}
|
|
103
|
+
}
|
|
104
104
|
|
|
105
105
|
tablecell(content, flags) {
|
|
106
106
|
const type = flags.header ? 'th' : 'td';
|
|
@@ -108,28 +108,28 @@ module.exports = class Renderer {
|
|
|
108
108
|
? '<' + type + ' align="' + flags.align + '">'
|
|
109
109
|
: '<' + type + '>';
|
|
110
110
|
return tag + content + '</' + type + '>\n';
|
|
111
|
-
}
|
|
111
|
+
}
|
|
112
112
|
|
|
113
113
|
// span level renderer
|
|
114
114
|
strong(text) {
|
|
115
115
|
return '<strong>' + text + '</strong>';
|
|
116
|
-
}
|
|
116
|
+
}
|
|
117
117
|
|
|
118
118
|
em(text) {
|
|
119
119
|
return '<em>' + text + '</em>';
|
|
120
|
-
}
|
|
120
|
+
}
|
|
121
121
|
|
|
122
122
|
codespan(text) {
|
|
123
123
|
return '<code>' + text + '</code>';
|
|
124
|
-
}
|
|
124
|
+
}
|
|
125
125
|
|
|
126
126
|
br() {
|
|
127
127
|
return this.options.xhtml ? '<br/>' : '<br>';
|
|
128
|
-
}
|
|
128
|
+
}
|
|
129
129
|
|
|
130
130
|
del(text) {
|
|
131
131
|
return '<del>' + text + '</del>';
|
|
132
|
-
}
|
|
132
|
+
}
|
|
133
133
|
|
|
134
134
|
link(href, title, text) {
|
|
135
135
|
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
@@ -142,7 +142,7 @@ module.exports = class Renderer {
|
|
|
142
142
|
}
|
|
143
143
|
out += '>' + text + '</a>';
|
|
144
144
|
return out;
|
|
145
|
-
}
|
|
145
|
+
}
|
|
146
146
|
|
|
147
147
|
image(href, title, text) {
|
|
148
148
|
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
@@ -156,9 +156,9 @@ module.exports = class Renderer {
|
|
|
156
156
|
}
|
|
157
157
|
out += this.options.xhtml ? '/>' : '>';
|
|
158
158
|
return out;
|
|
159
|
-
}
|
|
159
|
+
}
|
|
160
160
|
|
|
161
161
|
text(text) {
|
|
162
162
|
return text;
|
|
163
|
-
}
|
|
163
|
+
}
|
|
164
164
|
};
|
package/src/Slugger.js
CHANGED