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.
@@ -1,293 +0,0 @@
1
- const Renderer = require('./Renderer.js');
2
- const { defaults } = require('./defaults.js');
3
- const { inline } = require('./rules.js');
4
- const {
5
- findClosingBracket,
6
- escape
7
- } = require('./helpers.js');
8
-
9
- /**
10
- * Inline Lexer & Compiler
11
- */
12
- module.exports = class InlineLexer {
13
- constructor(links, options) {
14
- this.options = options || defaults;
15
- this.links = links;
16
- this.rules = inline.normal;
17
- this.options.renderer = this.options.renderer || new Renderer();
18
- this.renderer = this.options.renderer;
19
- this.renderer.options = this.options;
20
-
21
- if (!this.links) {
22
- throw new Error('Tokens array requires a `links` property.');
23
- }
24
-
25
- if (this.options.pedantic) {
26
- this.rules = inline.pedantic;
27
- } else if (this.options.gfm) {
28
- if (this.options.breaks) {
29
- this.rules = inline.breaks;
30
- } else {
31
- this.rules = inline.gfm;
32
- }
33
- }
34
- }
35
-
36
- /**
37
- * Expose Inline Rules
38
- */
39
- static get rules() {
40
- return inline;
41
- }
42
-
43
- /**
44
- * Static Lexing/Compiling Method
45
- */
46
- static output(src, links, options) {
47
- const inline = new InlineLexer(links, options);
48
- return inline.output(src);
49
- }
50
-
51
- /**
52
- * Lexing/Compiling
53
- */
54
- output(src) {
55
- let out = '',
56
- link,
57
- text,
58
- href,
59
- title,
60
- cap,
61
- prevCapZero;
62
-
63
- while (src) {
64
- // escape
65
- if (cap = this.rules.escape.exec(src)) {
66
- src = src.substring(cap[0].length);
67
- out += escape(cap[1]);
68
- continue;
69
- }
70
-
71
- // tag
72
- if (cap = this.rules.tag.exec(src)) {
73
- if (!this.inLink && /^<a /i.test(cap[0])) {
74
- this.inLink = true;
75
- } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
76
- this.inLink = false;
77
- }
78
- if (!this.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
79
- this.inRawBlock = true;
80
- } else if (this.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
81
- this.inRawBlock = false;
82
- }
83
-
84
- src = src.substring(cap[0].length);
85
- out += this.renderer.html(this.options.sanitize
86
- ? (this.options.sanitizer
87
- ? this.options.sanitizer(cap[0])
88
- : escape(cap[0]))
89
- : cap[0]);
90
- continue;
91
- }
92
-
93
- // link
94
- if (cap = this.rules.link.exec(src)) {
95
- const lastParenIndex = findClosingBracket(cap[2], '()');
96
- if (lastParenIndex > -1) {
97
- const start = cap[0].indexOf('!') === 0 ? 5 : 4;
98
- const linkLen = start + cap[1].length + lastParenIndex;
99
- cap[2] = cap[2].substring(0, lastParenIndex);
100
- cap[0] = cap[0].substring(0, linkLen).trim();
101
- cap[3] = '';
102
- }
103
- src = src.substring(cap[0].length);
104
- this.inLink = true;
105
- href = cap[2];
106
- if (this.options.pedantic) {
107
- link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
108
-
109
- if (link) {
110
- href = link[1];
111
- title = link[3];
112
- } else {
113
- title = '';
114
- }
115
- } else {
116
- title = cap[3] ? cap[3].slice(1, -1) : '';
117
- }
118
- href = href.trim().replace(/^<([\s\S]*)>$/, '$1');
119
- out += this.outputLink(cap, {
120
- href: InlineLexer.escapes(href),
121
- title: InlineLexer.escapes(title)
122
- });
123
- this.inLink = false;
124
- continue;
125
- }
126
-
127
- // reflink, nolink
128
- if ((cap = this.rules.reflink.exec(src))
129
- || (cap = this.rules.nolink.exec(src))) {
130
- src = src.substring(cap[0].length);
131
- link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
132
- link = this.links[link.toLowerCase()];
133
- if (!link || !link.href) {
134
- out += cap[0].charAt(0);
135
- src = cap[0].substring(1) + src;
136
- continue;
137
- }
138
- this.inLink = true;
139
- out += this.outputLink(cap, link);
140
- this.inLink = false;
141
- continue;
142
- }
143
-
144
- // strong
145
- if (cap = this.rules.strong.exec(src)) {
146
- src = src.substring(cap[0].length);
147
- out += this.renderer.strong(this.output(cap[4] || cap[3] || cap[2] || cap[1]));
148
- continue;
149
- }
150
-
151
- // em
152
- if (cap = this.rules.em.exec(src)) {
153
- src = src.substring(cap[0].length);
154
- out += this.renderer.em(this.output(cap[6] || cap[5] || cap[4] || cap[3] || cap[2] || cap[1]));
155
- continue;
156
- }
157
-
158
- // code
159
- if (cap = this.rules.code.exec(src)) {
160
- src = src.substring(cap[0].length);
161
- out += this.renderer.codespan(escape(cap[2].trim(), true));
162
- continue;
163
- }
164
-
165
- // br
166
- if (cap = this.rules.br.exec(src)) {
167
- src = src.substring(cap[0].length);
168
- out += this.renderer.br();
169
- continue;
170
- }
171
-
172
- // del (gfm)
173
- if (cap = this.rules.del.exec(src)) {
174
- src = src.substring(cap[0].length);
175
- out += this.renderer.del(this.output(cap[1]));
176
- continue;
177
- }
178
-
179
- // autolink
180
- if (cap = this.rules.autolink.exec(src)) {
181
- src = src.substring(cap[0].length);
182
- if (cap[2] === '@') {
183
- text = escape(this.mangle(cap[1]));
184
- href = 'mailto:' + text;
185
- } else {
186
- text = escape(cap[1]);
187
- href = text;
188
- }
189
- out += this.renderer.link(href, null, text);
190
- continue;
191
- }
192
-
193
- // url (gfm)
194
- if (!this.inLink && (cap = this.rules.url.exec(src))) {
195
- if (cap[2] === '@') {
196
- text = escape(cap[0]);
197
- href = 'mailto:' + text;
198
- } else {
199
- // do extended autolink path validation
200
- do {
201
- prevCapZero = cap[0];
202
- cap[0] = this.rules._backpedal.exec(cap[0])[0];
203
- } while (prevCapZero !== cap[0]);
204
- text = escape(cap[0]);
205
- if (cap[1] === 'www.') {
206
- href = 'http://' + text;
207
- } else {
208
- href = text;
209
- }
210
- }
211
- src = src.substring(cap[0].length);
212
- out += this.renderer.link(href, null, text);
213
- continue;
214
- }
215
-
216
- // text
217
- if (cap = this.rules.text.exec(src)) {
218
- src = src.substring(cap[0].length);
219
- if (this.inRawBlock) {
220
- out += this.renderer.text(this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0]);
221
- } else {
222
- out += this.renderer.text(escape(this.smartypants(cap[0])));
223
- }
224
- continue;
225
- }
226
-
227
- if (src) {
228
- throw new Error('Infinite loop on byte: ' + src.charCodeAt(0));
229
- }
230
- }
231
-
232
- return out;
233
- }
234
-
235
- static escapes(text) {
236
- return text ? text.replace(InlineLexer.rules._escapes, '$1') : text;
237
- }
238
-
239
- /**
240
- * Compile Link
241
- */
242
- outputLink(cap, link) {
243
- const href = link.href,
244
- title = link.title ? escape(link.title) : null;
245
-
246
- return cap[0].charAt(0) !== '!'
247
- ? this.renderer.link(href, title, this.output(cap[1]))
248
- : this.renderer.image(href, title, escape(cap[1]));
249
- }
250
-
251
- /**
252
- * Smartypants Transformations
253
- */
254
- smartypants(text) {
255
- if (!this.options.smartypants) return text;
256
- return text
257
- // em-dashes
258
- .replace(/---/g, '\u2014')
259
- // en-dashes
260
- .replace(/--/g, '\u2013')
261
- // opening singles
262
- .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
263
- // closing singles & apostrophes
264
- .replace(/'/g, '\u2019')
265
- // opening doubles
266
- .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
267
- // closing doubles
268
- .replace(/"/g, '\u201d')
269
- // ellipses
270
- .replace(/\.{3}/g, '\u2026');
271
- }
272
-
273
- /**
274
- * Mangle Links
275
- */
276
- mangle(text) {
277
- if (!this.options.mangle) return text;
278
- const l = text.length;
279
- let out = '',
280
- i = 0,
281
- ch;
282
-
283
- for (; i < l; i++) {
284
- ch = text.charCodeAt(i);
285
- if (Math.random() > 0.5) {
286
- ch = 'x' + ch.toString(16);
287
- }
288
- out += '&#' + ch + ';';
289
- }
290
-
291
- return out;
292
- }
293
- };