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