marked 1.0.0 → 1.1.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/lib/marked.esm.js CHANGED
@@ -32,6 +32,7 @@ function getDefaults() {
32
32
  smartLists: false,
33
33
  smartypants: false,
34
34
  tokenizer: null,
35
+ walkTokens: null,
35
36
  xhtml: false
36
37
  };
37
38
  }
@@ -325,6 +326,34 @@ function outputLink(cap, link, raw) {
325
326
  }
326
327
  }
327
328
 
329
+ function indentCodeCompensation(raw, text) {
330
+ const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
331
+
332
+ if (matchIndentToCode === null) {
333
+ return text;
334
+ }
335
+
336
+ const indentToCode = matchIndentToCode[1];
337
+
338
+ return text
339
+ .split('\n')
340
+ .map(node => {
341
+ const matchIndentInNode = node.match(/^\s+/);
342
+ if (matchIndentInNode === null) {
343
+ return node;
344
+ }
345
+
346
+ const [indentInNode] = matchIndentInNode;
347
+
348
+ if (indentInNode.length >= indentToCode.length) {
349
+ return node.slice(indentToCode.length);
350
+ }
351
+
352
+ return node;
353
+ })
354
+ .join('\n');
355
+ }
356
+
328
357
  /**
329
358
  * Tokenizer
330
359
  */
@@ -352,32 +381,35 @@ var Tokenizer_1 = class Tokenizer {
352
381
  const lastToken = tokens[tokens.length - 1];
353
382
  // An indented code block cannot interrupt a paragraph.
354
383
  if (lastToken && lastToken.type === 'paragraph') {
355
- tokens.pop();
356
- lastToken.text += '\n' + cap[0].trimRight();
357
- lastToken.raw += '\n' + cap[0];
358
- return lastToken;
359
- } else {
360
- const text = cap[0].replace(/^ {4}/gm, '');
361
384
  return {
362
- type: 'code',
363
385
  raw: cap[0],
364
- codeBlockStyle: 'indented',
365
- text: !this.options.pedantic
366
- ? rtrim$1(text, '\n')
367
- : text
386
+ text: cap[0].trimRight()
368
387
  };
369
388
  }
389
+
390
+ const text = cap[0].replace(/^ {4}/gm, '');
391
+ return {
392
+ type: 'code',
393
+ raw: cap[0],
394
+ codeBlockStyle: 'indented',
395
+ text: !this.options.pedantic
396
+ ? rtrim$1(text, '\n')
397
+ : text
398
+ };
370
399
  }
371
400
  }
372
401
 
373
402
  fences(src) {
374
403
  const cap = this.rules.block.fences.exec(src);
375
404
  if (cap) {
405
+ const raw = cap[0];
406
+ const text = indentCodeCompensation(raw, cap[3] || '');
407
+
376
408
  return {
377
409
  type: 'code',
378
- raw: cap[0],
410
+ raw,
379
411
  lang: cap[2] ? cap[2].trim() : cap[2],
380
- text: cap[3] || ''
412
+ text
381
413
  };
382
414
  }
383
415
  }
@@ -534,6 +566,7 @@ var Tokenizer_1 = class Tokenizer {
534
566
  }
535
567
 
536
568
  list.items.push({
569
+ type: 'list_item',
537
570
  raw,
538
571
  task: istask,
539
572
  checked: ischecked,
@@ -639,9 +672,17 @@ var Tokenizer_1 = class Tokenizer {
639
672
  }
640
673
  }
641
674
 
642
- text(src) {
675
+ text(src, tokens) {
643
676
  const cap = this.rules.block.text.exec(src);
644
677
  if (cap) {
678
+ const lastToken = tokens[tokens.length - 1];
679
+ if (lastToken && lastToken.type === 'text') {
680
+ return {
681
+ raw: cap[0],
682
+ text: cap[0]
683
+ };
684
+ }
685
+
645
686
  return {
646
687
  type: 'text',
647
688
  raw: cap[0],
@@ -769,10 +810,17 @@ var Tokenizer_1 = class Tokenizer {
769
810
  codespan(src) {
770
811
  const cap = this.rules.inline.code.exec(src);
771
812
  if (cap) {
813
+ let text = cap[2].replace(/\n/g, ' ');
814
+ const hasNonSpaceChars = /[^ ]/.test(text);
815
+ const hasSpaceCharsOnBothEnds = text.startsWith(' ') && text.endsWith(' ');
816
+ if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
817
+ text = text.substring(1, text.length - 1);
818
+ }
819
+ text = escape$1(text, true);
772
820
  return {
773
821
  type: 'codespan',
774
822
  raw: cap[0],
775
- text: escape$1(cap[2].trim(), true)
823
+ text
776
824
  };
777
825
  }
778
826
  }
@@ -1052,7 +1100,7 @@ const inline = {
1052
1100
  reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
1053
1101
  nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
1054
1102
  strong: /^__([^\s_])__(?!_)|^\*\*([^\s*])\*\*(?!\*)|^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)/,
1055
- em: /^_([^\s_])_(?!_)|^_([^\s_<][\s\S]*?[^\s_])_(?!_|[^\spunctuation])|^_([^\s_<][\s\S]*?[^\s])_(?!_|[^\spunctuation])|^\*([^\s*<\[])\*(?!\*)|^\*([^\s<"][\s\S]*?[^\s\[\*])\*(?![\]`punctuation])|^\*([^\s*"<\[][\s\S]*[^\s])\*(?!\*)/,
1103
+ em: /^_([^\s_])_(?!_)|^_([^\s_<][\s\S]*?[^\s_])_(?!_|[^\s,punctuation])|^_([^\s_<][\s\S]*?[^\s])_(?!_|[^\s,punctuation])|^\*([^\s*<\[])\*(?!\*)|^\*([^\s<"][\s\S]*?[^\s\[\*])\*(?![\]`punctuation])|^\*([^\s*"<\[][\s\S]*[^\s])\*(?!\*)/,
1056
1104
  code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
1057
1105
  br: /^( {2,}|\\)\n(?!\s*$)/,
1058
1106
  del: noopTest$1,
@@ -1061,6 +1109,7 @@ const inline = {
1061
1109
 
1062
1110
  // list of punctuation marks from common mark spec
1063
1111
  // without ` and ] to workaround Rule 17 (inline code blocks/links)
1112
+ // without , to work around example 393
1064
1113
  inline._punctuation = '!"#$%&\'()*+\\-./:;<=>?@\\[^_{|}~';
1065
1114
  inline.em = edit$1(inline.em).replace(/punctuation/g, inline._punctuation).getRegex();
1066
1115
 
@@ -1261,7 +1310,7 @@ var Lexer_1 = class Lexer {
1261
1310
  */
1262
1311
  blockTokens(src, tokens = [], top = true) {
1263
1312
  src = src.replace(/^ +$/gm, '');
1264
- let token, i, l;
1313
+ let token, i, l, lastToken;
1265
1314
 
1266
1315
  while (src) {
1267
1316
  // newline
@@ -1276,7 +1325,13 @@ var Lexer_1 = class Lexer {
1276
1325
  // code
1277
1326
  if (token = this.tokenizer.code(src, tokens)) {
1278
1327
  src = src.substring(token.raw.length);
1279
- tokens.push(token);
1328
+ if (token.type) {
1329
+ tokens.push(token);
1330
+ } else {
1331
+ lastToken = tokens[tokens.length - 1];
1332
+ lastToken.raw += '\n' + token.raw;
1333
+ lastToken.text += '\n' + token.text;
1334
+ }
1280
1335
  continue;
1281
1336
  }
1282
1337
 
@@ -1368,9 +1423,15 @@ var Lexer_1 = class Lexer {
1368
1423
  }
1369
1424
 
1370
1425
  // text
1371
- if (token = this.tokenizer.text(src)) {
1426
+ if (token = this.tokenizer.text(src, tokens)) {
1372
1427
  src = src.substring(token.raw.length);
1373
- tokens.push(token);
1428
+ if (token.type) {
1429
+ tokens.push(token);
1430
+ } else {
1431
+ lastToken = tokens[tokens.length - 1];
1432
+ lastToken.raw += '\n' + token.raw;
1433
+ lastToken.text += '\n' + token.text;
1434
+ }
1374
1435
  continue;
1375
1436
  }
1376
1437
 
@@ -1594,7 +1655,7 @@ var Renderer_1 = class Renderer {
1594
1655
  if (!lang) {
1595
1656
  return '<pre><code>'
1596
1657
  + (escaped ? code : escape$2(code, true))
1597
- + '</code></pre>';
1658
+ + '</code></pre>\n';
1598
1659
  }
1599
1660
 
1600
1661
  return '<pre><code class="'
@@ -1938,7 +1999,7 @@ var Parser_1 = class Parser {
1938
1999
  if (item.task) {
1939
2000
  checkbox = this.renderer.checkbox(checked);
1940
2001
  if (loose) {
1941
- if (item.tokens[0].type === 'text') {
2002
+ if (item.tokens.length > 0 && item.tokens[0].type === 'text') {
1942
2003
  item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
1943
2004
  if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
1944
2005
  item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
@@ -2086,18 +2147,17 @@ function marked(src, opt, callback) {
2086
2147
  + Object.prototype.toString.call(src) + ', string expected');
2087
2148
  }
2088
2149
 
2089
- if (callback || typeof opt === 'function') {
2090
- if (!callback) {
2091
- callback = opt;
2092
- opt = null;
2093
- }
2150
+ if (typeof opt === 'function') {
2151
+ callback = opt;
2152
+ opt = null;
2153
+ }
2154
+
2155
+ opt = merge$2({}, marked.defaults, opt || {});
2156
+ checkSanitizeDeprecation$1(opt);
2094
2157
 
2095
- opt = merge$2({}, marked.defaults, opt || {});
2096
- checkSanitizeDeprecation$1(opt);
2158
+ if (callback) {
2097
2159
  const highlight = opt.highlight;
2098
- let tokens,
2099
- pending,
2100
- i = 0;
2160
+ let tokens;
2101
2161
 
2102
2162
  try {
2103
2163
  tokens = Lexer_1.lex(src, opt);
@@ -2105,20 +2165,15 @@ function marked(src, opt, callback) {
2105
2165
  return callback(e);
2106
2166
  }
2107
2167
 
2108
- pending = tokens.length;
2109
-
2110
2168
  const done = function(err) {
2111
- if (err) {
2112
- opt.highlight = highlight;
2113
- return callback(err);
2114
- }
2115
-
2116
2169
  let out;
2117
2170
 
2118
- try {
2119
- out = Parser_1.parse(tokens, opt);
2120
- } catch (e) {
2121
- err = e;
2171
+ if (!err) {
2172
+ try {
2173
+ out = Parser_1.parse(tokens, opt);
2174
+ } catch (e) {
2175
+ err = e;
2176
+ }
2122
2177
  }
2123
2178
 
2124
2179
  opt.highlight = highlight;
@@ -2134,34 +2189,45 @@ function marked(src, opt, callback) {
2134
2189
 
2135
2190
  delete opt.highlight;
2136
2191
 
2137
- if (!pending) return done();
2192
+ if (!tokens.length) return done();
2138
2193
 
2139
- for (; i < tokens.length; i++) {
2140
- (function(token) {
2141
- if (token.type !== 'code') {
2142
- return --pending || done();
2143
- }
2144
- return highlight(token.text, token.lang, function(err, code) {
2145
- if (err) return done(err);
2146
- if (code == null || code === token.text) {
2147
- return --pending || done();
2194
+ let pending = 0;
2195
+ marked.walkTokens(tokens, function(token) {
2196
+ if (token.type === 'code') {
2197
+ pending++;
2198
+ highlight(token.text, token.lang, function(err, code) {
2199
+ if (err) {
2200
+ return done(err);
2201
+ }
2202
+ if (code != null && code !== token.text) {
2203
+ token.text = code;
2204
+ token.escaped = true;
2205
+ }
2206
+
2207
+ pending--;
2208
+ if (pending === 0) {
2209
+ done();
2148
2210
  }
2149
- token.text = code;
2150
- token.escaped = true;
2151
- --pending || done();
2152
2211
  });
2153
- })(tokens[i]);
2212
+ }
2213
+ });
2214
+
2215
+ if (pending === 0) {
2216
+ done();
2154
2217
  }
2155
2218
 
2156
2219
  return;
2157
2220
  }
2221
+
2158
2222
  try {
2159
- opt = merge$2({}, marked.defaults, opt || {});
2160
- checkSanitizeDeprecation$1(opt);
2161
- return Parser_1.parse(Lexer_1.lex(src, opt), opt);
2223
+ const tokens = Lexer_1.lex(src, opt);
2224
+ if (opt.walkTokens) {
2225
+ marked.walkTokens(tokens, opt.walkTokens);
2226
+ }
2227
+ return Parser_1.parse(tokens, opt);
2162
2228
  } catch (e) {
2163
2229
  e.message += '\nPlease report this to https://github.com/markedjs/marked.';
2164
- if ((opt || marked.defaults).silent) {
2230
+ if (opt.silent) {
2165
2231
  return '<p>An error occurred:</p><pre>'
2166
2232
  + escape$3(e.message + '', true)
2167
2233
  + '</pre>';
@@ -2219,9 +2285,50 @@ marked.use = function(extension) {
2219
2285
  }
2220
2286
  opts.tokenizer = tokenizer;
2221
2287
  }
2288
+ if (extension.walkTokens) {
2289
+ const walkTokens = marked.defaults.walkTokens;
2290
+ opts.walkTokens = (token) => {
2291
+ extension.walkTokens(token);
2292
+ if (walkTokens) {
2293
+ walkTokens(token);
2294
+ }
2295
+ };
2296
+ }
2222
2297
  marked.setOptions(opts);
2223
2298
  };
2224
2299
 
2300
+ /**
2301
+ * Run callback for every token
2302
+ */
2303
+
2304
+ marked.walkTokens = function(tokens, callback) {
2305
+ for (const token of tokens) {
2306
+ callback(token);
2307
+ switch (token.type) {
2308
+ case 'table': {
2309
+ for (const cell of token.tokens.header) {
2310
+ marked.walkTokens(cell, callback);
2311
+ }
2312
+ for (const row of token.tokens.cells) {
2313
+ for (const cell of row) {
2314
+ marked.walkTokens(cell, callback);
2315
+ }
2316
+ }
2317
+ break;
2318
+ }
2319
+ case 'list': {
2320
+ marked.walkTokens(token.items, callback);
2321
+ break;
2322
+ }
2323
+ default: {
2324
+ if (token.tokens) {
2325
+ marked.walkTokens(token.tokens, callback);
2326
+ }
2327
+ }
2328
+ }
2329
+ }
2330
+ };
2331
+
2225
2332
  /**
2226
2333
  * Expose
2227
2334
  */