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