marked 1.2.7 → 2.0.1

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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * marked - a markdown parser
3
- * Copyright (c) 2011-2020, Christopher Jeffrey. (MIT Licensed)
3
+ * Copyright (c) 2011-2021, Christopher Jeffrey. (MIT Licensed)
4
4
  * https://github.com/markedjs/marked
5
5
  */
6
6
 
@@ -73,8 +73,9 @@
73
73
  return it.next.bind(it);
74
74
  }
75
75
 
76
- function createCommonjsModule(fn, module) {
77
- return module = { exports: {} }, fn(module, module.exports), module.exports;
76
+ function createCommonjsModule(fn) {
77
+ var module = { exports: {} };
78
+ return fn(module, module.exports), module.exports;
78
79
  }
79
80
 
80
81
  var defaults = createCommonjsModule(function (module) {
@@ -111,9 +112,6 @@
111
112
  changeDefaults: changeDefaults
112
113
  };
113
114
  });
114
- var defaults_1 = defaults.defaults;
115
- var defaults_2 = defaults.getDefaults;
116
- var defaults_3 = defaults.changeDefaults;
117
115
 
118
116
  /**
119
117
  * Helpers
@@ -490,20 +488,11 @@
490
488
  }
491
489
  };
492
490
 
493
- _proto.code = function code(src, tokens) {
491
+ _proto.code = function code(src) {
494
492
  var cap = this.rules.block.code.exec(src);
495
493
 
496
494
  if (cap) {
497
- var lastToken = tokens[tokens.length - 1]; // An indented code block cannot interrupt a paragraph.
498
-
499
- if (lastToken && lastToken.type === 'paragraph') {
500
- return {
501
- raw: cap[0],
502
- text: cap[0].trimRight()
503
- };
504
- }
505
-
506
- var text = cap[0].replace(/^ {4}/gm, '');
495
+ var text = cap[0].replace(/^ {1,4}/gm, '');
507
496
  return {
508
497
  type: 'code',
509
498
  raw: cap[0],
@@ -642,31 +631,44 @@
642
631
  addBack,
643
632
  loose,
644
633
  istask,
645
- ischecked;
634
+ ischecked,
635
+ endMatch;
646
636
  var l = itemMatch.length;
647
637
  bcurr = this.rules.block.listItemStart.exec(itemMatch[0]);
648
638
 
649
639
  for (var i = 0; i < l; i++) {
650
640
  item = itemMatch[i];
651
- raw = item; // Determine whether the next list item belongs here.
641
+ raw = item;
642
+
643
+ if (!this.options.pedantic) {
644
+ // Determine if current item contains the end of the list
645
+ endMatch = item.match(new RegExp('\\n\\s*\\n {0,' + (bcurr[0].length - 1) + '}\\S'));
646
+
647
+ if (endMatch) {
648
+ addBack = item.length - endMatch.index + itemMatch.slice(i + 1).join('\n').length;
649
+ list.raw = list.raw.substring(0, list.raw.length - addBack);
650
+ item = item.substring(0, endMatch.index);
651
+ raw = item;
652
+ l = i + 1;
653
+ }
654
+ } // Determine whether the next list item belongs here.
652
655
  // Backpedal if it does not belong in this list.
653
656
 
657
+
654
658
  if (i !== l - 1) {
655
659
  bnext = this.rules.block.listItemStart.exec(itemMatch[i + 1]);
656
660
 
657
- if (bnext[1].length > bcurr[0].length || bnext[1].length > 3) {
658
- // nested list
659
- itemMatch.splice(i, 2, itemMatch[i] + '\n' + itemMatch[i + 1]);
661
+ if (!this.options.pedantic ? bnext[1].length >= bcurr[0].length || bnext[1].length > 3 : bnext[1].length > bcurr[1].length) {
662
+ // nested list or continuation
663
+ itemMatch.splice(i, 2, itemMatch[i] + (!this.options.pedantic && bnext[1].length < bcurr[0].length && !itemMatch[i].match(/\n$/) ? '' : '\n') + itemMatch[i + 1]);
660
664
  i--;
661
665
  l--;
662
666
  continue;
663
- } else {
664
- if ( // different bullet style
665
- !this.options.pedantic || this.options.smartLists ? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1] : isordered === (bnext[2].length === 1)) {
666
- addBack = itemMatch.slice(i + 1).join('\n');
667
- list.raw = list.raw.substring(0, list.raw.length - addBack.length);
668
- i = l - 1;
669
- }
667
+ } else if ( // different bullet style
668
+ !this.options.pedantic || this.options.smartLists ? bnext[2][bnext[2].length - 1] !== bull[bull.length - 1] : isordered === (bnext[2].length === 1)) {
669
+ addBack = itemMatch.slice(i + 1).join('\n').length;
670
+ list.raw = list.raw.substring(0, list.raw.length - addBack);
671
+ i = l - 1;
670
672
  }
671
673
 
672
674
  bcurr = bnext;
@@ -681,15 +683,22 @@
681
683
  if (~item.indexOf('\n ')) {
682
684
  space -= item.length;
683
685
  item = !this.options.pedantic ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') : item.replace(/^ {1,4}/gm, '');
686
+ } // trim item newlines at end
687
+
688
+
689
+ item = rtrim$1(item, '\n');
690
+
691
+ if (i !== l - 1) {
692
+ raw = raw + '\n';
684
693
  } // Determine whether item is loose or not.
685
694
  // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
686
695
  // for discount behavior.
687
696
 
688
697
 
689
- loose = next || /\n\n(?!\s*$)/.test(item);
698
+ loose = next || /\n\n(?!\s*$)/.test(raw);
690
699
 
691
700
  if (i !== l - 1) {
692
- next = item.charAt(item.length - 1) === '\n';
701
+ next = raw.slice(-2) === '\n\n';
693
702
  if (!loose) loose = next;
694
703
  }
695
704
 
@@ -814,19 +823,10 @@
814
823
  }
815
824
  };
816
825
 
817
- _proto.text = function text(src, tokens) {
826
+ _proto.text = function text(src) {
818
827
  var cap = this.rules.block.text.exec(src);
819
828
 
820
829
  if (cap) {
821
- var lastToken = tokens[tokens.length - 1];
822
-
823
- if (lastToken && lastToken.type === 'text') {
824
- return {
825
- raw: cap[0],
826
- text: cap[0]
827
- };
828
- }
829
-
830
830
  return {
831
831
  type: 'text',
832
832
  raw: cap[0],
@@ -957,54 +957,66 @@
957
957
  }
958
958
  };
959
959
 
960
- _proto.strong = function strong(src, maskedSrc, prevChar) {
960
+ _proto.emStrong = function emStrong(src, maskedSrc, prevChar) {
961
961
  if (prevChar === void 0) {
962
962
  prevChar = '';
963
963
  }
964
964
 
965
- var match = this.rules.inline.strong.start.exec(src);
965
+ var match = this.rules.inline.emStrong.lDelim.exec(src);
966
+ if (!match) return;
967
+ if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/)) return; // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
968
+
969
+ var nextChar = match[1] || match[2] || '';
966
970
 
967
- if (match && (!match[1] || match[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
968
- maskedSrc = maskedSrc.slice(-1 * src.length);
969
- var endReg = match[0] === '**' ? this.rules.inline.strong.endAst : this.rules.inline.strong.endUnd;
971
+ if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) {
972
+ var lLength = match[0].length - 1;
973
+ var rDelim,
974
+ rLength,
975
+ delimTotal = lLength,
976
+ midDelimTotal = 0;
977
+ var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
970
978
  endReg.lastIndex = 0;
971
- var cap;
979
+ maskedSrc = maskedSrc.slice(-1 * src.length + lLength); // Bump maskedSrc to same section of string as src (move to lexer?)
972
980
 
973
981
  while ((match = endReg.exec(maskedSrc)) != null) {
974
- cap = this.rules.inline.strong.middle.exec(maskedSrc.slice(0, match.index + 3));
975
-
976
- if (cap) {
977
- return {
978
- type: 'strong',
979
- raw: src.slice(0, cap[0].length),
980
- text: src.slice(2, cap[0].length - 2)
981
- };
982
+ rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
983
+ if (!rDelim) continue; // matched the first alternative in rules.js (skip the * in __abc*abc__)
984
+
985
+ rLength = rDelim.length;
986
+
987
+ if (match[3] || match[4]) {
988
+ // found another Left Delim
989
+ delimTotal += rLength;
990
+ continue;
991
+ } else if (match[5] || match[6]) {
992
+ // either Left or Right Delim
993
+ if (lLength % 3 && !((lLength + rLength) % 3)) {
994
+ midDelimTotal += rLength;
995
+ continue; // CommonMark Emphasis Rules 9-10
996
+ }
982
997
  }
983
- }
984
- }
985
- };
986
998
 
987
- _proto.em = function em(src, maskedSrc, prevChar) {
988
- if (prevChar === void 0) {
989
- prevChar = '';
990
- }
991
-
992
- var match = this.rules.inline.em.start.exec(src);
993
-
994
- if (match && (!match[1] || match[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
995
- maskedSrc = maskedSrc.slice(-1 * src.length);
996
- var endReg = match[0] === '*' ? this.rules.inline.em.endAst : this.rules.inline.em.endUnd;
997
- endReg.lastIndex = 0;
998
- var cap;
999
+ delimTotal -= rLength;
1000
+ if (delimTotal > 0) continue; // Haven't found enough closing delimiters
1001
+ // If this is the last rDelimiter, remove extra characters. *a*** -> *a*
999
1002
 
1000
- while ((match = endReg.exec(maskedSrc)) != null) {
1001
- cap = this.rules.inline.em.middle.exec(maskedSrc.slice(0, match.index + 2));
1003
+ if (delimTotal + midDelimTotal - rLength <= 0 && !maskedSrc.slice(endReg.lastIndex).match(endReg)) {
1004
+ rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
1005
+ }
1002
1006
 
1003
- if (cap) {
1007
+ if (Math.min(lLength, rLength) % 2) {
1004
1008
  return {
1005
1009
  type: 'em',
1006
- raw: src.slice(0, cap[0].length),
1007
- text: src.slice(1, cap[0].length - 1)
1010
+ raw: src.slice(0, lLength + match.index + rLength + 1),
1011
+ text: src.slice(1, lLength + match.index + rLength)
1012
+ };
1013
+ }
1014
+
1015
+ if (Math.min(lLength, rLength) % 2 === 0) {
1016
+ return {
1017
+ type: 'strong',
1018
+ raw: src.slice(0, lLength + match.index + rLength + 1),
1019
+ text: src.slice(2, lLength + match.index + rLength - 1)
1008
1020
  };
1009
1021
  }
1010
1022
  }
@@ -1155,8 +1167,8 @@
1155
1167
  */
1156
1168
 
1157
1169
  var block = {
1158
- newline: /^\n+/,
1159
- code: /^( {4}[^\n]+\n*)+/,
1170
+ newline: /^(?: *(?:\n|$))+/,
1171
+ code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
1160
1172
  fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,
1161
1173
  hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
1162
1174
  heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
@@ -1178,7 +1190,7 @@
1178
1190
  lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,
1179
1191
  // regex template, placeholders will be replaced according to different paragraph
1180
1192
  // interruption rules of commonmark and the original markdown spec:
1181
- _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html)[^\n]+)*)/,
1193
+ _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,
1182
1194
  text: /^[^\n]+/
1183
1195
  };
1184
1196
  block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
@@ -1187,7 +1199,7 @@
1187
1199
  block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
1188
1200
  block.item = /^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/;
1189
1201
  block.item = edit$1(block.item, 'gm').replace(/bull/g, block.bullet).getRegex();
1190
- block.listItemStart = edit$1(/^( *)(bull)/).replace('bull', block.bullet).getRegex();
1202
+ block.listItemStart = edit$1(/^( *)(bull) */).replace('bull', block.bullet).getRegex();
1191
1203
  block.list = edit$1(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex();
1192
1204
  block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul';
1193
1205
  block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
@@ -1253,48 +1265,31 @@
1253
1265
  reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
1254
1266
  nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
1255
1267
  reflinkSearch: 'reflink|nolink(?!\\()',
1256
- strong: {
1257
- start: /^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/,
1258
- // (1) returns if starts w/ punctuation
1259
- middle: /^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,
1260
- endAst: /[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/,
1261
- // last char can't be punct, or final * must also be followed by punct (or endline)
1262
- endUnd: /[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
1263
-
1264
- },
1265
- em: {
1266
- start: /^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/,
1267
- // (1) returns if starts w/ punctuation
1268
- middle: /^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,
1269
- endAst: /[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/,
1270
- // last char can't be punct, or final * must also be followed by punct (or endline)
1271
- endUnd: /[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/ // last char can't be a space, and final _ must preceed punct or \s (or endline)
1268
+ emStrong: {
1269
+ lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
1270
+ // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
1271
+ // () Skip other delimiter (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
1272
+ rDelimAst: /\_\_[^_]*?\*[^_]*?\_\_|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
1273
+ rDelimUnd: /\*\*[^*]*?\_[^*]*?\*\*|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
1272
1274
 
1273
1275
  },
1274
1276
  code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
1275
1277
  br: /^( {2,}|\\)\n(?!\s*$)/,
1276
1278
  del: noopTest$1,
1277
- text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n)))/,
1278
- punctuation: /^([\s*punctuation])/
1279
- }; // list of punctuation marks from common mark spec
1280
- // without * and _ to workaround cases with double emphasis
1279
+ text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
1280
+ punctuation: /^([\spunctuation])/
1281
+ }; // list of punctuation marks from CommonMark spec
1282
+ // without * and _ to handle the different emphasis markers * and _
1281
1283
 
1282
1284
  inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
1283
1285
  inline.punctuation = edit$1(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); // sequences em should skip over [title](link), `code`, <html>
1284
1286
 
1285
- inline._blockSkip = '\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>';
1286
- inline._overlapSkip = '__[^_]*?__|\\*\\*\\[^\\*\\]*?\\*\\*';
1287
+ inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
1288
+ inline.escapedEmSt = /\\\*|\\_/g;
1287
1289
  inline._comment = edit$1(block._comment).replace('(?:-->|$)', '-->').getRegex();
1288
- inline.em.start = edit$1(inline.em.start).replace(/punctuation/g, inline._punctuation).getRegex();
1289
- inline.em.middle = edit$1(inline.em.middle).replace(/punctuation/g, inline._punctuation).replace(/overlapSkip/g, inline._overlapSkip).getRegex();
1290
- inline.em.endAst = edit$1(inline.em.endAst, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
1291
- inline.em.endUnd = edit$1(inline.em.endUnd, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
1292
- inline.strong.start = edit$1(inline.strong.start).replace(/punctuation/g, inline._punctuation).getRegex();
1293
- inline.strong.middle = edit$1(inline.strong.middle).replace(/punctuation/g, inline._punctuation).replace(/overlapSkip/g, inline._overlapSkip).getRegex();
1294
- inline.strong.endAst = edit$1(inline.strong.endAst, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
1295
- inline.strong.endUnd = edit$1(inline.strong.endUnd, 'g').replace(/punctuation/g, inline._punctuation).getRegex();
1296
- inline.blockSkip = edit$1(inline._blockSkip, 'g').getRegex();
1297
- inline.overlapSkip = edit$1(inline._overlapSkip, 'g').getRegex();
1290
+ inline.emStrong.lDelim = edit$1(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex();
1291
+ inline.emStrong.rDelimAst = edit$1(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex();
1292
+ inline.emStrong.rDelimUnd = edit$1(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex();
1298
1293
  inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
1299
1294
  inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
1300
1295
  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])?)+(?![-_])/;
@@ -1342,7 +1337,7 @@
1342
1337
  url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
1343
1338
  _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
1344
1339
  del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
1345
- text: /^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
1340
+ text: /^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/
1346
1341
  });
1347
1342
  inline.gfm.url = edit$1(inline.gfm.url, 'i').replace('email', inline.gfm._extended_email).getRegex();
1348
1343
  /**
@@ -1480,7 +1475,10 @@
1480
1475
  top = true;
1481
1476
  }
1482
1477
 
1483
- src = src.replace(/^ +$/gm, '');
1478
+ if (this.options.pedantic) {
1479
+ src = src.replace(/^ +$/gm, '');
1480
+ }
1481
+
1484
1482
  var token, i, l, lastToken;
1485
1483
 
1486
1484
  while (src) {
@@ -1496,15 +1494,15 @@
1496
1494
  } // code
1497
1495
 
1498
1496
 
1499
- if (token = this.tokenizer.code(src, tokens)) {
1497
+ if (token = this.tokenizer.code(src)) {
1500
1498
  src = src.substring(token.raw.length);
1499
+ lastToken = tokens[tokens.length - 1]; // An indented code block cannot interrupt a paragraph.
1501
1500
 
1502
- if (token.type) {
1503
- tokens.push(token);
1504
- } else {
1505
- lastToken = tokens[tokens.length - 1];
1501
+ if (lastToken && lastToken.type === 'paragraph') {
1506
1502
  lastToken.raw += '\n' + token.raw;
1507
1503
  lastToken.text += '\n' + token.text;
1504
+ } else {
1505
+ tokens.push(token);
1508
1506
  }
1509
1507
 
1510
1508
  continue;
@@ -1602,15 +1600,15 @@
1602
1600
  } // text
1603
1601
 
1604
1602
 
1605
- if (token = this.tokenizer.text(src, tokens)) {
1603
+ if (token = this.tokenizer.text(src)) {
1606
1604
  src = src.substring(token.raw.length);
1605
+ lastToken = tokens[tokens.length - 1];
1607
1606
 
1608
- if (token.type) {
1609
- tokens.push(token);
1610
- } else {
1611
- lastToken = tokens[tokens.length - 1];
1607
+ if (lastToken && lastToken.type === 'text') {
1612
1608
  lastToken.raw += '\n' + token.raw;
1613
1609
  lastToken.text += '\n' + token.text;
1610
+ } else {
1611
+ tokens.push(token);
1614
1612
  }
1615
1613
 
1616
1614
  continue;
@@ -1717,7 +1715,7 @@
1717
1715
  inRawBlock = false;
1718
1716
  }
1719
1717
 
1720
- var token; // String with links masked to avoid interference with em and strong
1718
+ var token, lastToken; // String with links masked to avoid interference with em and strong
1721
1719
 
1722
1720
  var maskedSrc = src;
1723
1721
  var match;
@@ -1738,6 +1736,11 @@
1738
1736
 
1739
1737
  while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
1740
1738
  maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString$1('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
1739
+ } // Mask out escaped em & strong delimiters
1740
+
1741
+
1742
+ while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
1743
+ maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
1741
1744
  }
1742
1745
 
1743
1746
  while (src) {
@@ -1758,7 +1761,15 @@
1758
1761
  src = src.substring(token.raw.length);
1759
1762
  inLink = token.inLink;
1760
1763
  inRawBlock = token.inRawBlock;
1761
- tokens.push(token);
1764
+ var _lastToken = tokens[tokens.length - 1];
1765
+
1766
+ if (_lastToken && token.type === 'text' && _lastToken.type === 'text') {
1767
+ _lastToken.raw += token.raw;
1768
+ _lastToken.text += token.text;
1769
+ } else {
1770
+ tokens.push(token);
1771
+ }
1772
+
1762
1773
  continue;
1763
1774
  } // link
1764
1775
 
@@ -1777,25 +1788,23 @@
1777
1788
 
1778
1789
  if (token = this.tokenizer.reflink(src, this.tokens.links)) {
1779
1790
  src = src.substring(token.raw.length);
1791
+ var _lastToken2 = tokens[tokens.length - 1];
1780
1792
 
1781
1793
  if (token.type === 'link') {
1782
1794
  token.tokens = this.inlineTokens(token.text, [], true, inRawBlock);
1795
+ tokens.push(token);
1796
+ } else if (_lastToken2 && token.type === 'text' && _lastToken2.type === 'text') {
1797
+ _lastToken2.raw += token.raw;
1798
+ _lastToken2.text += token.text;
1799
+ } else {
1800
+ tokens.push(token);
1783
1801
  }
1784
1802
 
1785
- tokens.push(token);
1786
- continue;
1787
- } // strong
1788
-
1789
-
1790
- if (token = this.tokenizer.strong(src, maskedSrc, prevChar)) {
1791
- src = src.substring(token.raw.length);
1792
- token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
1793
- tokens.push(token);
1794
1803
  continue;
1795
- } // em
1804
+ } // em & strong
1796
1805
 
1797
1806
 
1798
- if (token = this.tokenizer.em(src, maskedSrc, prevChar)) {
1807
+ if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
1799
1808
  src = src.substring(token.raw.length);
1800
1809
  token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
1801
1810
  tokens.push(token);
@@ -1841,9 +1850,22 @@
1841
1850
 
1842
1851
  if (token = this.tokenizer.inlineText(src, inRawBlock, smartypants)) {
1843
1852
  src = src.substring(token.raw.length);
1844
- prevChar = token.raw.slice(-1);
1853
+
1854
+ if (token.raw.slice(-1) !== '_') {
1855
+ // Track prevChar before string of ____ started
1856
+ prevChar = token.raw.slice(-1);
1857
+ }
1858
+
1845
1859
  keepPrevChar = true;
1846
- tokens.push(token);
1860
+ lastToken = tokens[tokens.length - 1];
1861
+
1862
+ if (lastToken && lastToken.type === 'text') {
1863
+ lastToken.raw += token.raw;
1864
+ lastToken.text += token.text;
1865
+ } else {
1866
+ tokens.push(token);
1867
+ }
1868
+
1847
1869
  continue;
1848
1870
  }
1849
1871
 
@@ -1901,6 +1923,8 @@
1901
1923
  }
1902
1924
  }
1903
1925
 
1926
+ _code = _code.replace(/\n$/, '') + '\n';
1927
+
1904
1928
  if (!lang) {
1905
1929
  return '<pre><code>' + (escaped ? _code : escape$1(_code, true)) + '</code></pre>\n';
1906
1930
  }