marked 9.1.6 → 11.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 +12 -3
- package/lib/marked.cjs +286 -282
- package/lib/marked.cjs.map +1 -1
- package/lib/marked.d.cts +142 -22
- package/lib/marked.d.ts +142 -22
- package/lib/marked.esm.js +286 -282
- package/lib/marked.esm.js.map +1 -1
- package/lib/marked.umd.js +286 -282
- package/lib/marked.umd.js.map +1 -1
- package/man/marked.1 +1 -1
- package/marked.min.js +2 -2
- package/package.json +17 -20
package/lib/marked.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* marked
|
|
2
|
+
* marked v11.0.0 - a markdown parser
|
|
3
3
|
* Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
|
|
4
4
|
* https://github.com/markedjs/marked
|
|
5
5
|
*/
|
|
@@ -48,7 +48,7 @@ const escapeReplacements = {
|
|
|
48
48
|
"'": '''
|
|
49
49
|
};
|
|
50
50
|
const getEscapeReplacement = (ch) => escapeReplacements[ch];
|
|
51
|
-
function escape(html, encode) {
|
|
51
|
+
function escape$1(html, encode) {
|
|
52
52
|
if (encode) {
|
|
53
53
|
if (escapeTest.test(html)) {
|
|
54
54
|
return html.replace(escapeReplace, getEscapeReplacement);
|
|
@@ -78,17 +78,17 @@ function unescape(html) {
|
|
|
78
78
|
}
|
|
79
79
|
const caret = /(^|[^\[])\^/g;
|
|
80
80
|
function edit(regex, opt) {
|
|
81
|
-
|
|
81
|
+
let source = typeof regex === 'string' ? regex : regex.source;
|
|
82
82
|
opt = opt || '';
|
|
83
83
|
const obj = {
|
|
84
84
|
replace: (name, val) => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
let valSource = typeof val === 'string' ? val : val.source;
|
|
86
|
+
valSource = valSource.replace(caret, '$1');
|
|
87
|
+
source = source.replace(name, valSource);
|
|
88
88
|
return obj;
|
|
89
89
|
},
|
|
90
90
|
getRegex: () => {
|
|
91
|
-
return new RegExp(
|
|
91
|
+
return new RegExp(source, opt);
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
94
|
return obj;
|
|
@@ -198,7 +198,7 @@ function findClosingBracket(str, b) {
|
|
|
198
198
|
|
|
199
199
|
function outputLink(cap, link, raw, lexer) {
|
|
200
200
|
const href = link.href;
|
|
201
|
-
const title = link.title ? escape(link.title) : null;
|
|
201
|
+
const title = link.title ? escape$1(link.title) : null;
|
|
202
202
|
const text = cap[1].replace(/\\([\[\]])/g, '$1');
|
|
203
203
|
if (cap[0].charAt(0) !== '!') {
|
|
204
204
|
lexer.state.inLink = true;
|
|
@@ -218,7 +218,7 @@ function outputLink(cap, link, raw, lexer) {
|
|
|
218
218
|
raw,
|
|
219
219
|
href,
|
|
220
220
|
title,
|
|
221
|
-
text: escape(text)
|
|
221
|
+
text: escape$1(text)
|
|
222
222
|
};
|
|
223
223
|
}
|
|
224
224
|
function indentCodeCompensation(raw, text) {
|
|
@@ -247,9 +247,8 @@ function indentCodeCompensation(raw, text) {
|
|
|
247
247
|
*/
|
|
248
248
|
class _Tokenizer {
|
|
249
249
|
options;
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
lexer;
|
|
250
|
+
rules; // set by the lexer
|
|
251
|
+
lexer; // set by the lexer
|
|
253
252
|
constructor(options) {
|
|
254
253
|
this.options = options || exports.defaults;
|
|
255
254
|
}
|
|
@@ -284,7 +283,7 @@ class _Tokenizer {
|
|
|
284
283
|
return {
|
|
285
284
|
type: 'code',
|
|
286
285
|
raw,
|
|
287
|
-
lang: cap[2] ? cap[2].trim().replace(this.rules.inline.
|
|
286
|
+
lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],
|
|
288
287
|
text
|
|
289
288
|
};
|
|
290
289
|
}
|
|
@@ -482,7 +481,7 @@ class _Tokenizer {
|
|
|
482
481
|
}
|
|
483
482
|
// Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
|
|
484
483
|
list.items[list.items.length - 1].raw = raw.trimEnd();
|
|
485
|
-
list.items[list.items.length - 1].text = itemContents.trimEnd();
|
|
484
|
+
(list.items[list.items.length - 1]).text = itemContents.trimEnd();
|
|
486
485
|
list.raw = list.raw.trimEnd();
|
|
487
486
|
// Item child tokens handled here at end because we needed to have the final item to trim it first
|
|
488
487
|
for (let i = 0; i < list.items.length; i++) {
|
|
@@ -521,8 +520,8 @@ class _Tokenizer {
|
|
|
521
520
|
const cap = this.rules.block.def.exec(src);
|
|
522
521
|
if (cap) {
|
|
523
522
|
const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
|
|
524
|
-
const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline.
|
|
525
|
-
const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.
|
|
523
|
+
const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';
|
|
524
|
+
const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];
|
|
526
525
|
return {
|
|
527
526
|
type: 'def',
|
|
528
527
|
tag,
|
|
@@ -534,63 +533,56 @@ class _Tokenizer {
|
|
|
534
533
|
}
|
|
535
534
|
table(src) {
|
|
536
535
|
const cap = this.rules.block.table.exec(src);
|
|
537
|
-
if (cap) {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
536
|
+
if (!cap) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (!/[:|]/.test(cap[2])) {
|
|
540
|
+
// delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
const headers = splitCells(cap[1]);
|
|
544
|
+
const aligns = cap[2].replace(/^\||\| *$/g, '').split('|');
|
|
545
|
+
const rows = cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [];
|
|
546
|
+
const item = {
|
|
547
|
+
type: 'table',
|
|
548
|
+
raw: cap[0],
|
|
549
|
+
header: [],
|
|
550
|
+
align: [],
|
|
551
|
+
rows: []
|
|
552
|
+
};
|
|
553
|
+
if (headers.length !== aligns.length) {
|
|
554
|
+
// header and align columns must be equal, rows can be different.
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
for (const align of aligns) {
|
|
558
|
+
if (/^ *-+: *$/.test(align)) {
|
|
559
|
+
item.align.push('right');
|
|
541
560
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}),
|
|
548
|
-
align: cap[2].replace(/^\||\| *$/g, '').split('|'),
|
|
549
|
-
rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
|
|
550
|
-
};
|
|
551
|
-
if (item.header.length === item.align.length) {
|
|
552
|
-
let l = item.align.length;
|
|
553
|
-
let i, j, k, row;
|
|
554
|
-
for (i = 0; i < l; i++) {
|
|
555
|
-
const align = item.align[i];
|
|
556
|
-
if (align) {
|
|
557
|
-
if (/^ *-+: *$/.test(align)) {
|
|
558
|
-
item.align[i] = 'right';
|
|
559
|
-
}
|
|
560
|
-
else if (/^ *:-+: *$/.test(align)) {
|
|
561
|
-
item.align[i] = 'center';
|
|
562
|
-
}
|
|
563
|
-
else if (/^ *:-+ *$/.test(align)) {
|
|
564
|
-
item.align[i] = 'left';
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
item.align[i] = null;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
l = item.rows.length;
|
|
572
|
-
for (i = 0; i < l; i++) {
|
|
573
|
-
item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => {
|
|
574
|
-
return { text: c, tokens: [] };
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
// parse child tokens inside headers and cells
|
|
578
|
-
// header child tokens
|
|
579
|
-
l = item.header.length;
|
|
580
|
-
for (j = 0; j < l; j++) {
|
|
581
|
-
item.header[j].tokens = this.lexer.inline(item.header[j].text);
|
|
582
|
-
}
|
|
583
|
-
// cell child tokens
|
|
584
|
-
l = item.rows.length;
|
|
585
|
-
for (j = 0; j < l; j++) {
|
|
586
|
-
row = item.rows[j];
|
|
587
|
-
for (k = 0; k < row.length; k++) {
|
|
588
|
-
row[k].tokens = this.lexer.inline(row[k].text);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
return item;
|
|
561
|
+
else if (/^ *:-+: *$/.test(align)) {
|
|
562
|
+
item.align.push('center');
|
|
563
|
+
}
|
|
564
|
+
else if (/^ *:-+ *$/.test(align)) {
|
|
565
|
+
item.align.push('left');
|
|
592
566
|
}
|
|
567
|
+
else {
|
|
568
|
+
item.align.push(null);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
for (const header of headers) {
|
|
572
|
+
item.header.push({
|
|
573
|
+
text: header,
|
|
574
|
+
tokens: this.lexer.inline(header)
|
|
575
|
+
});
|
|
593
576
|
}
|
|
577
|
+
for (const row of rows) {
|
|
578
|
+
item.rows.push(splitCells(row, item.header.length).map(cell => {
|
|
579
|
+
return {
|
|
580
|
+
text: cell,
|
|
581
|
+
tokens: this.lexer.inline(cell)
|
|
582
|
+
};
|
|
583
|
+
}));
|
|
584
|
+
}
|
|
585
|
+
return item;
|
|
594
586
|
}
|
|
595
587
|
lheading(src) {
|
|
596
588
|
const cap = this.rules.block.lheading.exec(src);
|
|
@@ -635,7 +627,7 @@ class _Tokenizer {
|
|
|
635
627
|
return {
|
|
636
628
|
type: 'escape',
|
|
637
629
|
raw: cap[0],
|
|
638
|
-
text: escape(cap[1])
|
|
630
|
+
text: escape$1(cap[1])
|
|
639
631
|
};
|
|
640
632
|
}
|
|
641
633
|
}
|
|
@@ -714,8 +706,8 @@ class _Tokenizer {
|
|
|
714
706
|
}
|
|
715
707
|
}
|
|
716
708
|
return outputLink(cap, {
|
|
717
|
-
href: href ? href.replace(this.rules.inline.
|
|
718
|
-
title: title ? title.replace(this.rules.inline.
|
|
709
|
+
href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,
|
|
710
|
+
title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title
|
|
719
711
|
}, cap[0], this.lexer);
|
|
720
712
|
}
|
|
721
713
|
}
|
|
@@ -723,8 +715,8 @@ class _Tokenizer {
|
|
|
723
715
|
let cap;
|
|
724
716
|
if ((cap = this.rules.inline.reflink.exec(src))
|
|
725
717
|
|| (cap = this.rules.inline.nolink.exec(src))) {
|
|
726
|
-
|
|
727
|
-
link = links[
|
|
718
|
+
const linkString = (cap[2] || cap[1]).replace(/\s+/g, ' ');
|
|
719
|
+
const link = links[linkString.toLowerCase()];
|
|
728
720
|
if (!link) {
|
|
729
721
|
const text = cap[0].charAt(0);
|
|
730
722
|
return {
|
|
@@ -737,7 +729,7 @@ class _Tokenizer {
|
|
|
737
729
|
}
|
|
738
730
|
}
|
|
739
731
|
emStrong(src, maskedSrc, prevChar = '') {
|
|
740
|
-
let match = this.rules.inline.
|
|
732
|
+
let match = this.rules.inline.emStrongLDelim.exec(src);
|
|
741
733
|
if (!match)
|
|
742
734
|
return;
|
|
743
735
|
// _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
|
|
@@ -748,7 +740,7 @@ class _Tokenizer {
|
|
|
748
740
|
// unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
|
|
749
741
|
const lLength = [...match[0]].length - 1;
|
|
750
742
|
let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
|
|
751
|
-
const endReg = match[0][0] === '*' ? this.rules.inline.
|
|
743
|
+
const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
|
|
752
744
|
endReg.lastIndex = 0;
|
|
753
745
|
// Clip maskedSrc to same section of string as src (move to lexer?)
|
|
754
746
|
maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
|
|
@@ -805,7 +797,7 @@ class _Tokenizer {
|
|
|
805
797
|
if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
|
|
806
798
|
text = text.substring(1, text.length - 1);
|
|
807
799
|
}
|
|
808
|
-
text = escape(text, true);
|
|
800
|
+
text = escape$1(text, true);
|
|
809
801
|
return {
|
|
810
802
|
type: 'codespan',
|
|
811
803
|
raw: cap[0],
|
|
@@ -838,11 +830,11 @@ class _Tokenizer {
|
|
|
838
830
|
if (cap) {
|
|
839
831
|
let text, href;
|
|
840
832
|
if (cap[2] === '@') {
|
|
841
|
-
text = escape(cap[1]);
|
|
833
|
+
text = escape$1(cap[1]);
|
|
842
834
|
href = 'mailto:' + text;
|
|
843
835
|
}
|
|
844
836
|
else {
|
|
845
|
-
text = escape(cap[1]);
|
|
837
|
+
text = escape$1(cap[1]);
|
|
846
838
|
href = text;
|
|
847
839
|
}
|
|
848
840
|
return {
|
|
@@ -865,7 +857,7 @@ class _Tokenizer {
|
|
|
865
857
|
if (cap = this.rules.inline.url.exec(src)) {
|
|
866
858
|
let text, href;
|
|
867
859
|
if (cap[2] === '@') {
|
|
868
|
-
text = escape(cap[0]);
|
|
860
|
+
text = escape$1(cap[0]);
|
|
869
861
|
href = 'mailto:' + text;
|
|
870
862
|
}
|
|
871
863
|
else {
|
|
@@ -873,9 +865,9 @@ class _Tokenizer {
|
|
|
873
865
|
let prevCapZero;
|
|
874
866
|
do {
|
|
875
867
|
prevCapZero = cap[0];
|
|
876
|
-
cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
|
|
868
|
+
cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';
|
|
877
869
|
} while (prevCapZero !== cap[0]);
|
|
878
|
-
text = escape(cap[0]);
|
|
870
|
+
text = escape$1(cap[0]);
|
|
879
871
|
if (cap[1] === 'www.') {
|
|
880
872
|
href = 'http://' + cap[0];
|
|
881
873
|
}
|
|
@@ -906,7 +898,7 @@ class _Tokenizer {
|
|
|
906
898
|
text = cap[0];
|
|
907
899
|
}
|
|
908
900
|
else {
|
|
909
|
-
text = escape(cap[0]);
|
|
901
|
+
text = escape$1(cap[0]);
|
|
910
902
|
}
|
|
911
903
|
return {
|
|
912
904
|
type: 'text',
|
|
@@ -920,66 +912,48 @@ class _Tokenizer {
|
|
|
920
912
|
/**
|
|
921
913
|
* Block-Level Grammar
|
|
922
914
|
*/
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
const
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
|
|
932
|
-
list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
|
|
933
|
-
html: '^ {0,3}(?:' // optional indentation
|
|
934
|
-
+ '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
|
|
935
|
-
+ '|comment[^\\n]*(\\n+|$)' // (2)
|
|
936
|
-
+ '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
|
|
937
|
-
+ '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
|
|
938
|
-
+ '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
|
|
939
|
-
+ '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
|
|
940
|
-
+ '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
|
|
941
|
-
+ '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
|
|
942
|
-
+ ')',
|
|
943
|
-
def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
|
|
944
|
-
table: noopTest,
|
|
945
|
-
lheading: /^(?!bull )((?:.|\n(?!\s*?\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
946
|
-
// regex template, placeholders will be replaced according to different paragraph
|
|
947
|
-
// interruption rules of commonmark and the original markdown spec:
|
|
948
|
-
_paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
|
|
949
|
-
text: /^[^\n]+/
|
|
950
|
-
};
|
|
951
|
-
block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
|
|
952
|
-
block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
|
|
953
|
-
block.def = edit(block.def)
|
|
954
|
-
.replace('label', block._label)
|
|
955
|
-
.replace('title', block._title)
|
|
915
|
+
const newline = /^(?: *(?:\n|$))+/;
|
|
916
|
+
const blockCode = /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/;
|
|
917
|
+
const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
|
|
918
|
+
const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
|
|
919
|
+
const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
|
|
920
|
+
const bullet = /(?:[*+-]|\d{1,9}[.)])/;
|
|
921
|
+
const lheading = edit(/^(?!bull )((?:.|\n(?!\s*?\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/)
|
|
922
|
+
.replace(/bull/g, bullet) // lists can interrupt
|
|
956
923
|
.getRegex();
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
924
|
+
const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
|
|
925
|
+
const blockText = /^[^\n]+/;
|
|
926
|
+
const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
|
|
927
|
+
const def = edit(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/)
|
|
928
|
+
.replace('label', _blockLabel)
|
|
929
|
+
.replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/)
|
|
960
930
|
.getRegex();
|
|
961
|
-
|
|
962
|
-
.replace(/bull/g,
|
|
963
|
-
.replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
|
|
964
|
-
.replace('def', '\\n+(?=' + block.def.source + ')')
|
|
931
|
+
const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/)
|
|
932
|
+
.replace(/bull/g, bullet)
|
|
965
933
|
.getRegex();
|
|
966
|
-
|
|
934
|
+
const _tag = 'address|article|aside|base|basefont|blockquote|body|caption'
|
|
967
935
|
+ '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
|
|
968
936
|
+ '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
|
|
969
937
|
+ '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
|
|
970
938
|
+ '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
|
|
971
939
|
+ '|track|ul';
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
940
|
+
const _comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
|
|
941
|
+
const html = edit('^ {0,3}(?:' // optional indentation
|
|
942
|
+
+ '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
|
|
943
|
+
+ '|comment[^\\n]*(\\n+|$)' // (2)
|
|
944
|
+
+ '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
|
|
945
|
+
+ '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
|
|
946
|
+
+ '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
|
|
947
|
+
+ '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
|
|
948
|
+
+ '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
|
|
949
|
+
+ '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
|
|
950
|
+
+ ')', 'i')
|
|
951
|
+
.replace('comment', _comment)
|
|
952
|
+
.replace('tag', _tag)
|
|
976
953
|
.replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
|
|
977
954
|
.getRegex();
|
|
978
|
-
|
|
979
|
-
.replace(
|
|
980
|
-
.getRegex();
|
|
981
|
-
block.paragraph = edit(block._paragraph)
|
|
982
|
-
.replace('hr', block.hr)
|
|
955
|
+
const paragraph = edit(_paragraph)
|
|
956
|
+
.replace('hr', hr)
|
|
983
957
|
.replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
|
|
984
958
|
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
|
|
985
959
|
.replace('|table', '')
|
|
@@ -987,54 +961,68 @@ block.paragraph = edit(block._paragraph)
|
|
|
987
961
|
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
988
962
|
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
989
963
|
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
990
|
-
.replace('tag',
|
|
964
|
+
.replace('tag', _tag) // pars can be interrupted by type (6) html blocks
|
|
991
965
|
.getRegex();
|
|
992
|
-
|
|
993
|
-
.replace('paragraph',
|
|
966
|
+
const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/)
|
|
967
|
+
.replace('paragraph', paragraph)
|
|
994
968
|
.getRegex();
|
|
995
969
|
/**
|
|
996
970
|
* Normal Block Grammar
|
|
997
971
|
*/
|
|
998
|
-
|
|
972
|
+
const blockNormal = {
|
|
973
|
+
blockquote,
|
|
974
|
+
code: blockCode,
|
|
975
|
+
def,
|
|
976
|
+
fences,
|
|
977
|
+
heading,
|
|
978
|
+
hr,
|
|
979
|
+
html,
|
|
980
|
+
lheading,
|
|
981
|
+
list,
|
|
982
|
+
newline,
|
|
983
|
+
paragraph,
|
|
984
|
+
table: noopTest,
|
|
985
|
+
text: blockText
|
|
986
|
+
};
|
|
999
987
|
/**
|
|
1000
988
|
* GFM Block Grammar
|
|
1001
989
|
*/
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
+ '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
|
|
1007
|
-
};
|
|
1008
|
-
block.gfm.table = edit(block.gfm.table)
|
|
1009
|
-
.replace('hr', block.hr)
|
|
990
|
+
const gfmTable = edit('^ *([^\\n ].*)\\n' // Header
|
|
991
|
+
+ ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align
|
|
992
|
+
+ '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells
|
|
993
|
+
.replace('hr', hr)
|
|
1010
994
|
.replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
|
|
1011
995
|
.replace('blockquote', ' {0,3}>')
|
|
1012
996
|
.replace('code', ' {4}[^\\n]')
|
|
1013
997
|
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
1014
998
|
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
1015
999
|
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
1016
|
-
.replace('tag',
|
|
1017
|
-
.getRegex();
|
|
1018
|
-
block.gfm.paragraph = edit(block._paragraph)
|
|
1019
|
-
.replace('hr', block.hr)
|
|
1020
|
-
.replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
|
|
1021
|
-
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
|
|
1022
|
-
.replace('table', block.gfm.table) // interrupt paragraphs with table
|
|
1023
|
-
.replace('blockquote', ' {0,3}>')
|
|
1024
|
-
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
1025
|
-
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
1026
|
-
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
1027
|
-
.replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
|
|
1000
|
+
.replace('tag', _tag) // tables can be interrupted by type (6) html blocks
|
|
1028
1001
|
.getRegex();
|
|
1002
|
+
const blockGfm = {
|
|
1003
|
+
...blockNormal,
|
|
1004
|
+
table: gfmTable,
|
|
1005
|
+
paragraph: edit(_paragraph)
|
|
1006
|
+
.replace('hr', hr)
|
|
1007
|
+
.replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
|
|
1008
|
+
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
|
|
1009
|
+
.replace('table', gfmTable) // interrupt paragraphs with table
|
|
1010
|
+
.replace('blockquote', ' {0,3}>')
|
|
1011
|
+
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
1012
|
+
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
1013
|
+
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
1014
|
+
.replace('tag', _tag) // pars can be interrupted by type (6) html blocks
|
|
1015
|
+
.getRegex()
|
|
1016
|
+
};
|
|
1029
1017
|
/**
|
|
1030
1018
|
* Pedantic grammar (original John Gruber's loose markdown specification)
|
|
1031
1019
|
*/
|
|
1032
|
-
|
|
1033
|
-
...
|
|
1020
|
+
const blockPedantic = {
|
|
1021
|
+
...blockNormal,
|
|
1034
1022
|
html: edit('^ *(?:comment *(?:\\n|\\s*$)'
|
|
1035
1023
|
+ '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
|
|
1036
1024
|
+ '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
|
|
1037
|
-
.replace('comment',
|
|
1025
|
+
.replace('comment', _comment)
|
|
1038
1026
|
.replace(/tag/g, '(?!(?:'
|
|
1039
1027
|
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
|
|
1040
1028
|
+ '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
|
|
@@ -1042,157 +1030,164 @@ block.pedantic = {
|
|
|
1042
1030
|
.getRegex(),
|
|
1043
1031
|
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
|
|
1044
1032
|
heading: /^(#{1,6})(.*)(?:\n+|$)/,
|
|
1045
|
-
fences: noopTest,
|
|
1033
|
+
fences: noopTest, // fences not supported
|
|
1046
1034
|
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
1047
|
-
paragraph: edit(
|
|
1048
|
-
.replace('hr',
|
|
1035
|
+
paragraph: edit(_paragraph)
|
|
1036
|
+
.replace('hr', hr)
|
|
1049
1037
|
.replace('heading', ' *#{1,6} *[^\n]')
|
|
1050
|
-
.replace('lheading',
|
|
1038
|
+
.replace('lheading', lheading)
|
|
1039
|
+
.replace('|table', '')
|
|
1051
1040
|
.replace('blockquote', ' {0,3}>')
|
|
1052
1041
|
.replace('|fences', '')
|
|
1053
1042
|
.replace('|list', '')
|
|
1054
1043
|
.replace('|html', '')
|
|
1044
|
+
.replace('|tag', '')
|
|
1055
1045
|
.getRegex()
|
|
1056
1046
|
};
|
|
1057
1047
|
/**
|
|
1058
1048
|
* Inline-Level Grammar
|
|
1059
1049
|
*/
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
|
|
1065
|
-
url: noopTest,
|
|
1066
|
-
tag: '^comment'
|
|
1067
|
-
+ '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
|
|
1068
|
-
+ '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
|
|
1069
|
-
+ '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
|
|
1070
|
-
+ '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
|
|
1071
|
-
+ '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
|
|
1072
|
-
link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
|
|
1073
|
-
reflink: /^!?\[(label)\]\[(ref)\]/,
|
|
1074
|
-
nolink: /^!?\[(ref)\](?:\[\])?/,
|
|
1075
|
-
reflinkSearch: 'reflink|nolink(?!\\()',
|
|
1076
|
-
emStrong: {
|
|
1077
|
-
lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
|
|
1078
|
-
// (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.
|
|
1079
|
-
// | Skip orphan inside strong | Consume to delim | (1) #*** | (2) a***#, a*** | (3) #***a, ***a | (4) ***# | (5) #***# | (6) a***a
|
|
1080
|
-
rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
|
|
1081
|
-
rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ // ^- Not allowed for _
|
|
1082
|
-
},
|
|
1083
|
-
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
|
|
1084
|
-
br: /^( {2,}|\\)\n(?!\s*$)/,
|
|
1085
|
-
del: noopTest,
|
|
1086
|
-
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
|
|
1087
|
-
punctuation: /^((?![*_])[\spunctuation])/
|
|
1088
|
-
};
|
|
1050
|
+
const escape = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
|
|
1051
|
+
const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
|
|
1052
|
+
const br = /^( {2,}|\\)\n(?!\s*$)/;
|
|
1053
|
+
const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
|
|
1089
1054
|
// list of unicode punctuation marks, plus any missing characters from CommonMark spec
|
|
1090
|
-
|
|
1091
|
-
|
|
1055
|
+
const _punctuation = '\\p{P}$+<=>`^|~';
|
|
1056
|
+
const punctuation = edit(/^((?![*_])[\spunctuation])/, 'u')
|
|
1057
|
+
.replace(/punctuation/g, _punctuation).getRegex();
|
|
1092
1058
|
// sequences em should skip over [title](link), `code`, <html>
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
|
|
1097
|
-
inline.emStrong.lDelim = edit(inline.emStrong.lDelim, 'u')
|
|
1098
|
-
.replace(/punct/g, inline._punctuation)
|
|
1099
|
-
.getRegex();
|
|
1100
|
-
inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'gu')
|
|
1101
|
-
.replace(/punct/g, inline._punctuation)
|
|
1059
|
+
const blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
|
|
1060
|
+
const emStrongLDelim = edit(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, 'u')
|
|
1061
|
+
.replace(/punct/g, _punctuation)
|
|
1102
1062
|
.getRegex();
|
|
1103
|
-
|
|
1104
|
-
|
|
1063
|
+
const emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
|
|
1064
|
+
+ '|[^*]+(?=[^*])' // Consume to delim
|
|
1065
|
+
+ '|(?!\\*)[punct](\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter
|
|
1066
|
+
+ '|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)' // (2) a***#, a*** can only be a Right Delimiter
|
|
1067
|
+
+ '|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])' // (3) #***a, ***a can only be Left Delimiter
|
|
1068
|
+
+ '|[\\s](\\*+)(?!\\*)(?=[punct])' // (4) ***# can only be Left Delimiter
|
|
1069
|
+
+ '|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])' // (5) #***# can be either Left or Right Delimiter
|
|
1070
|
+
+ '|[^punct\\s](\\*+)(?=[^punct\\s])', 'gu') // (6) a***a can be either Left or Right Delimiter
|
|
1071
|
+
.replace(/punct/g, _punctuation)
|
|
1105
1072
|
.getRegex();
|
|
1106
|
-
|
|
1107
|
-
|
|
1073
|
+
// (6) Not allowed for _
|
|
1074
|
+
const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong
|
|
1075
|
+
+ '|[^_]+(?=[^_])' // Consume to delim
|
|
1076
|
+
+ '|(?!_)[punct](_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter
|
|
1077
|
+
+ '|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)' // (2) a___#, a___ can only be a Right Delimiter
|
|
1078
|
+
+ '|(?!_)[punct\\s](_+)(?=[^punct\\s])' // (3) #___a, ___a can only be Left Delimiter
|
|
1079
|
+
+ '|[\\s](_+)(?!_)(?=[punct])' // (4) ___# can only be Left Delimiter
|
|
1080
|
+
+ '|(?!_)[punct](_+)(?!_)(?=[punct])', 'gu') // (5) #___# can be either Left or Right Delimiter
|
|
1081
|
+
.replace(/punct/g, _punctuation)
|
|
1108
1082
|
.getRegex();
|
|
1109
|
-
|
|
1110
|
-
.replace(/punct/g,
|
|
1083
|
+
const anyPunctuation = edit(/\\([punct])/, 'gu')
|
|
1084
|
+
.replace(/punct/g, _punctuation)
|
|
1111
1085
|
.getRegex();
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
.replace('scheme', inline._scheme)
|
|
1116
|
-
.replace('email', inline._email)
|
|
1086
|
+
const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/)
|
|
1087
|
+
.replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)
|
|
1088
|
+
.replace('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])?)+(?![-_])/)
|
|
1117
1089
|
.getRegex();
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1090
|
+
const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();
|
|
1091
|
+
const tag = edit('^comment'
|
|
1092
|
+
+ '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
|
|
1093
|
+
+ '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
|
|
1094
|
+
+ '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
|
|
1095
|
+
+ '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
|
|
1096
|
+
+ '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>') // CDATA section
|
|
1097
|
+
.replace('comment', _inlineComment)
|
|
1098
|
+
.replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/)
|
|
1122
1099
|
.getRegex();
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
.replace('
|
|
1128
|
-
.replace('href', inline._href)
|
|
1129
|
-
.replace('title', inline._title)
|
|
1100
|
+
const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
|
|
1101
|
+
const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/)
|
|
1102
|
+
.replace('label', _inlineLabel)
|
|
1103
|
+
.replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/)
|
|
1104
|
+
.replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/)
|
|
1130
1105
|
.getRegex();
|
|
1131
|
-
|
|
1132
|
-
.replace('label',
|
|
1133
|
-
.replace('ref',
|
|
1106
|
+
const reflink = edit(/^!?\[(label)\]\[(ref)\]/)
|
|
1107
|
+
.replace('label', _inlineLabel)
|
|
1108
|
+
.replace('ref', _blockLabel)
|
|
1134
1109
|
.getRegex();
|
|
1135
|
-
|
|
1136
|
-
.replace('ref',
|
|
1110
|
+
const nolink = edit(/^!?\[(ref)\](?:\[\])?/)
|
|
1111
|
+
.replace('ref', _blockLabel)
|
|
1137
1112
|
.getRegex();
|
|
1138
|
-
|
|
1139
|
-
.replace('reflink',
|
|
1140
|
-
.replace('nolink',
|
|
1113
|
+
const reflinkSearch = edit('reflink|nolink(?!\\()', 'g')
|
|
1114
|
+
.replace('reflink', reflink)
|
|
1115
|
+
.replace('nolink', nolink)
|
|
1141
1116
|
.getRegex();
|
|
1142
1117
|
/**
|
|
1143
1118
|
* Normal Inline Grammar
|
|
1144
1119
|
*/
|
|
1145
|
-
|
|
1120
|
+
const inlineNormal = {
|
|
1121
|
+
_backpedal: noopTest, // only used for GFM url
|
|
1122
|
+
anyPunctuation,
|
|
1123
|
+
autolink,
|
|
1124
|
+
blockSkip,
|
|
1125
|
+
br,
|
|
1126
|
+
code: inlineCode,
|
|
1127
|
+
del: noopTest,
|
|
1128
|
+
emStrongLDelim,
|
|
1129
|
+
emStrongRDelimAst,
|
|
1130
|
+
emStrongRDelimUnd,
|
|
1131
|
+
escape,
|
|
1132
|
+
link,
|
|
1133
|
+
nolink,
|
|
1134
|
+
punctuation,
|
|
1135
|
+
reflink,
|
|
1136
|
+
reflinkSearch,
|
|
1137
|
+
tag,
|
|
1138
|
+
text: inlineText,
|
|
1139
|
+
url: noopTest
|
|
1140
|
+
};
|
|
1146
1141
|
/**
|
|
1147
1142
|
* Pedantic Inline Grammar
|
|
1148
1143
|
*/
|
|
1149
|
-
|
|
1150
|
-
...
|
|
1151
|
-
strong: {
|
|
1152
|
-
start: /^__|\*\*/,
|
|
1153
|
-
middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
|
1154
|
-
endAst: /\*\*(?!\*)/g,
|
|
1155
|
-
endUnd: /__(?!_)/g
|
|
1156
|
-
},
|
|
1157
|
-
em: {
|
|
1158
|
-
start: /^_|\*/,
|
|
1159
|
-
middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
|
|
1160
|
-
endAst: /\*(?!\*)/g,
|
|
1161
|
-
endUnd: /_(?!_)/g
|
|
1162
|
-
},
|
|
1144
|
+
const inlinePedantic = {
|
|
1145
|
+
...inlineNormal,
|
|
1163
1146
|
link: edit(/^!?\[(label)\]\((.*?)\)/)
|
|
1164
|
-
.replace('label',
|
|
1147
|
+
.replace('label', _inlineLabel)
|
|
1165
1148
|
.getRegex(),
|
|
1166
1149
|
reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
|
|
1167
|
-
.replace('label',
|
|
1150
|
+
.replace('label', _inlineLabel)
|
|
1168
1151
|
.getRegex()
|
|
1169
1152
|
};
|
|
1170
1153
|
/**
|
|
1171
1154
|
* GFM Inline Grammar
|
|
1172
1155
|
*/
|
|
1173
|
-
|
|
1174
|
-
...
|
|
1175
|
-
escape: edit(
|
|
1176
|
-
|
|
1177
|
-
|
|
1156
|
+
const inlineGfm = {
|
|
1157
|
+
...inlineNormal,
|
|
1158
|
+
escape: edit(escape).replace('])', '~|])').getRegex(),
|
|
1159
|
+
url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i')
|
|
1160
|
+
.replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)
|
|
1161
|
+
.getRegex(),
|
|
1178
1162
|
_backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
|
|
1179
1163
|
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
|
|
1180
1164
|
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
|
|
1181
1165
|
};
|
|
1182
|
-
inline.gfm.url = edit(inline.gfm.url, 'i')
|
|
1183
|
-
.replace('email', inline.gfm._extended_email)
|
|
1184
|
-
.getRegex();
|
|
1185
1166
|
/**
|
|
1186
1167
|
* GFM + Line Breaks Inline Grammar
|
|
1187
1168
|
*/
|
|
1188
|
-
|
|
1189
|
-
...
|
|
1190
|
-
br: edit(
|
|
1191
|
-
text: edit(
|
|
1169
|
+
const inlineBreaks = {
|
|
1170
|
+
...inlineGfm,
|
|
1171
|
+
br: edit(br).replace('{2,}', '*').getRegex(),
|
|
1172
|
+
text: edit(inlineGfm.text)
|
|
1192
1173
|
.replace('\\b_', '\\b_| {2,}\\n')
|
|
1193
1174
|
.replace(/\{2,\}/g, '*')
|
|
1194
1175
|
.getRegex()
|
|
1195
1176
|
};
|
|
1177
|
+
/**
|
|
1178
|
+
* exports
|
|
1179
|
+
*/
|
|
1180
|
+
const block = {
|
|
1181
|
+
normal: blockNormal,
|
|
1182
|
+
gfm: blockGfm,
|
|
1183
|
+
pedantic: blockPedantic
|
|
1184
|
+
};
|
|
1185
|
+
const inline = {
|
|
1186
|
+
normal: inlineNormal,
|
|
1187
|
+
gfm: inlineGfm,
|
|
1188
|
+
breaks: inlineBreaks,
|
|
1189
|
+
pedantic: inlinePedantic
|
|
1190
|
+
};
|
|
1196
1191
|
|
|
1197
1192
|
/**
|
|
1198
1193
|
* Block Lexer
|
|
@@ -1205,7 +1200,6 @@ class _Lexer {
|
|
|
1205
1200
|
inlineQueue;
|
|
1206
1201
|
constructor(options) {
|
|
1207
1202
|
// TokenList cannot be created in one go
|
|
1208
|
-
// @ts-expect-error
|
|
1209
1203
|
this.tokens = [];
|
|
1210
1204
|
this.tokens.links = Object.create(null);
|
|
1211
1205
|
this.options = options || exports.defaults;
|
|
@@ -1639,13 +1633,13 @@ class _Renderer {
|
|
|
1639
1633
|
code = code.replace(/\n$/, '') + '\n';
|
|
1640
1634
|
if (!lang) {
|
|
1641
1635
|
return '<pre><code>'
|
|
1642
|
-
+ (escaped ? code : escape(code, true))
|
|
1636
|
+
+ (escaped ? code : escape$1(code, true))
|
|
1643
1637
|
+ '</code></pre>\n';
|
|
1644
1638
|
}
|
|
1645
1639
|
return '<pre><code class="language-'
|
|
1646
|
-
+ escape(lang)
|
|
1640
|
+
+ escape$1(lang)
|
|
1647
1641
|
+ '">'
|
|
1648
|
-
+ (escaped ? code : escape(code, true))
|
|
1642
|
+
+ (escaped ? code : escape$1(code, true))
|
|
1649
1643
|
+ '</code></pre>\n';
|
|
1650
1644
|
}
|
|
1651
1645
|
blockquote(quote) {
|
|
@@ -2169,11 +2163,14 @@ class Marked {
|
|
|
2169
2163
|
if (pack.renderer) {
|
|
2170
2164
|
const renderer = this.defaults.renderer || new _Renderer(this.defaults);
|
|
2171
2165
|
for (const prop in pack.renderer) {
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2166
|
+
if (!(prop in renderer) || prop === 'options') {
|
|
2167
|
+
throw new Error(`renderer '${prop}' does not exist`);
|
|
2168
|
+
}
|
|
2169
|
+
const rendererProp = prop;
|
|
2170
|
+
const rendererFunc = pack.renderer[rendererProp];
|
|
2171
|
+
const prevRenderer = renderer[rendererProp];
|
|
2175
2172
|
// Replace renderer with func to run extension, but fall back if false
|
|
2176
|
-
renderer[
|
|
2173
|
+
renderer[rendererProp] = (...args) => {
|
|
2177
2174
|
let ret = rendererFunc.apply(renderer, args);
|
|
2178
2175
|
if (ret === false) {
|
|
2179
2176
|
ret = prevRenderer.apply(renderer, args);
|
|
@@ -2186,11 +2183,15 @@ class Marked {
|
|
|
2186
2183
|
if (pack.tokenizer) {
|
|
2187
2184
|
const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
|
|
2188
2185
|
for (const prop in pack.tokenizer) {
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2186
|
+
if (!(prop in tokenizer) || ['options', 'rules', 'lexer'].includes(prop)) {
|
|
2187
|
+
throw new Error(`tokenizer '${prop}' does not exist`);
|
|
2188
|
+
}
|
|
2189
|
+
const tokenizerProp = prop;
|
|
2190
|
+
const tokenizerFunc = pack.tokenizer[tokenizerProp];
|
|
2191
|
+
const prevTokenizer = tokenizer[tokenizerProp];
|
|
2192
2192
|
// Replace tokenizer with func to run extension, but fall back if false
|
|
2193
|
-
|
|
2193
|
+
// @ts-expect-error cannot type tokenizer function dynamically
|
|
2194
|
+
tokenizer[tokenizerProp] = (...args) => {
|
|
2194
2195
|
let ret = tokenizerFunc.apply(tokenizer, args);
|
|
2195
2196
|
if (ret === false) {
|
|
2196
2197
|
ret = prevTokenizer.apply(tokenizer, args);
|
|
@@ -2204,11 +2205,14 @@ class Marked {
|
|
|
2204
2205
|
if (pack.hooks) {
|
|
2205
2206
|
const hooks = this.defaults.hooks || new _Hooks();
|
|
2206
2207
|
for (const prop in pack.hooks) {
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2208
|
+
if (!(prop in hooks) || prop === 'options') {
|
|
2209
|
+
throw new Error(`hook '${prop}' does not exist`);
|
|
2210
|
+
}
|
|
2211
|
+
const hooksProp = prop;
|
|
2212
|
+
const hooksFunc = pack.hooks[hooksProp];
|
|
2213
|
+
const prevHook = hooks[hooksProp];
|
|
2210
2214
|
if (_Hooks.passThroughHooks.has(prop)) {
|
|
2211
|
-
hooks[
|
|
2215
|
+
hooks[hooksProp] = (arg) => {
|
|
2212
2216
|
if (this.defaults.async) {
|
|
2213
2217
|
return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {
|
|
2214
2218
|
return prevHook.call(hooks, ret);
|
|
@@ -2219,7 +2223,7 @@ class Marked {
|
|
|
2219
2223
|
};
|
|
2220
2224
|
}
|
|
2221
2225
|
else {
|
|
2222
|
-
hooks[
|
|
2226
|
+
hooks[hooksProp] = (...args) => {
|
|
2223
2227
|
let ret = hooksFunc.apply(hooks, args);
|
|
2224
2228
|
if (ret === false) {
|
|
2225
2229
|
ret = prevHook.apply(hooks, args);
|
|
@@ -2312,7 +2316,7 @@ class Marked {
|
|
|
2312
2316
|
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
|
2313
2317
|
if (silent) {
|
|
2314
2318
|
const msg = '<p>An error occurred:</p><pre>'
|
|
2315
|
-
+ escape(e.message + '', true)
|
|
2319
|
+
+ escape$1(e.message + '', true)
|
|
2316
2320
|
+ '</pre>';
|
|
2317
2321
|
if (async) {
|
|
2318
2322
|
return Promise.resolve(msg);
|