marked 4.0.11 → 4.0.14
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/bin/marked.js +3 -0
- package/lib/marked.cjs +146 -44
- package/lib/marked.esm.js +121 -44
- package/lib/marked.umd.js +146 -44
- package/marked.min.js +1 -1
- package/package.json +12 -12
- package/src/Lexer.js +9 -3
- package/src/Renderer.js +63 -26
- package/src/Slugger.js +8 -2
- package/src/Tokenizer.js +2 -2
- package/src/helpers.js +33 -6
- package/src/marked.js +1 -0
- package/src/rules.js +5 -5
package/lib/marked.esm.js
CHANGED
|
@@ -70,6 +70,9 @@ function escape(html, encode) {
|
|
|
70
70
|
|
|
71
71
|
const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* @param {string} html
|
|
75
|
+
*/
|
|
73
76
|
function unescape(html) {
|
|
74
77
|
// explicitly match decimal, hex, and named HTML entities
|
|
75
78
|
return html.replace(unescapeTest, (_, n) => {
|
|
@@ -85,8 +88,13 @@ function unescape(html) {
|
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
const caret = /(^|[^\[])\^/g;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {string | RegExp} regex
|
|
94
|
+
* @param {string} opt
|
|
95
|
+
*/
|
|
88
96
|
function edit(regex, opt) {
|
|
89
|
-
regex = regex
|
|
97
|
+
regex = typeof regex === 'string' ? regex : regex.source;
|
|
90
98
|
opt = opt || '';
|
|
91
99
|
const obj = {
|
|
92
100
|
replace: (name, val) => {
|
|
@@ -104,6 +112,12 @@ function edit(regex, opt) {
|
|
|
104
112
|
|
|
105
113
|
const nonWordAndColonTest = /[^\w:]/g;
|
|
106
114
|
const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {boolean} sanitize
|
|
118
|
+
* @param {string} base
|
|
119
|
+
* @param {string} href
|
|
120
|
+
*/
|
|
107
121
|
function cleanUrl(sanitize, base, href) {
|
|
108
122
|
if (sanitize) {
|
|
109
123
|
let prot;
|
|
@@ -134,6 +148,10 @@ const justDomain = /^[^:]+:\/*[^/]*$/;
|
|
|
134
148
|
const protocol = /^([^:]+:)[\s\S]*$/;
|
|
135
149
|
const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
|
|
136
150
|
|
|
151
|
+
/**
|
|
152
|
+
* @param {string} base
|
|
153
|
+
* @param {string} href
|
|
154
|
+
*/
|
|
137
155
|
function resolveUrl(base, href) {
|
|
138
156
|
if (!baseUrls[' ' + base]) {
|
|
139
157
|
// we can ignore everything in base after the last slash of its path component,
|
|
@@ -203,7 +221,7 @@ function splitCells(tableRow, count) {
|
|
|
203
221
|
|
|
204
222
|
// First/last cell in a row cannot be empty if it has no leading/trailing pipe
|
|
205
223
|
if (!cells[0].trim()) { cells.shift(); }
|
|
206
|
-
if (!cells[cells.length - 1].trim()) { cells.pop(); }
|
|
224
|
+
if (cells.length > 0 && !cells[cells.length - 1].trim()) { cells.pop(); }
|
|
207
225
|
|
|
208
226
|
if (cells.length > count) {
|
|
209
227
|
cells.splice(count);
|
|
@@ -218,9 +236,14 @@ function splitCells(tableRow, count) {
|
|
|
218
236
|
return cells;
|
|
219
237
|
}
|
|
220
238
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
|
|
241
|
+
* /c*$/ is vulnerable to REDOS.
|
|
242
|
+
*
|
|
243
|
+
* @param {string} str
|
|
244
|
+
* @param {string} c
|
|
245
|
+
* @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
|
|
246
|
+
*/
|
|
224
247
|
function rtrim(str, c, invert) {
|
|
225
248
|
const l = str.length;
|
|
226
249
|
if (l === 0) {
|
|
@@ -242,7 +265,7 @@ function rtrim(str, c, invert) {
|
|
|
242
265
|
}
|
|
243
266
|
}
|
|
244
267
|
|
|
245
|
-
return str.
|
|
268
|
+
return str.slice(0, l - suffLen);
|
|
246
269
|
}
|
|
247
270
|
|
|
248
271
|
function findClosingBracket(str, b) {
|
|
@@ -274,6 +297,10 @@ function checkSanitizeDeprecation(opt) {
|
|
|
274
297
|
}
|
|
275
298
|
|
|
276
299
|
// copied from https://stackoverflow.com/a/5450113/806777
|
|
300
|
+
/**
|
|
301
|
+
* @param {string} pattern
|
|
302
|
+
* @param {number} count
|
|
303
|
+
*/
|
|
277
304
|
function repeatString(pattern, count) {
|
|
278
305
|
if (count < 1) {
|
|
279
306
|
return '';
|
|
@@ -434,7 +461,7 @@ class Tokenizer {
|
|
|
434
461
|
blockquote(src) {
|
|
435
462
|
const cap = this.rules.block.blockquote.exec(src);
|
|
436
463
|
if (cap) {
|
|
437
|
-
const text = cap[0].replace(/^ *> ?/gm, '');
|
|
464
|
+
const text = cap[0].replace(/^ *>[ \t]?/gm, '');
|
|
438
465
|
|
|
439
466
|
return {
|
|
440
467
|
type: 'blockquote',
|
|
@@ -470,7 +497,7 @@ class Tokenizer {
|
|
|
470
497
|
}
|
|
471
498
|
|
|
472
499
|
// Get next list item
|
|
473
|
-
const itemRegex = new RegExp(`^( {0,3}${bull})((?: [^\\n]*)?(?:\\n|$))`);
|
|
500
|
+
const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
|
|
474
501
|
|
|
475
502
|
// Check if current bullet point can start a new List Item
|
|
476
503
|
while (src) {
|
|
@@ -1057,10 +1084,10 @@ const block = {
|
|
|
1057
1084
|
newline: /^(?: *(?:\n|$))+/,
|
|
1058
1085
|
code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
|
|
1059
1086
|
fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
|
|
1060
|
-
hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
|
|
1087
|
+
hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
|
|
1061
1088
|
heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
|
|
1062
1089
|
blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
|
|
1063
|
-
list: /^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,
|
|
1090
|
+
list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
|
|
1064
1091
|
html: '^ {0,3}(?:' // optional indentation
|
|
1065
1092
|
+ '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
|
|
1066
1093
|
+ '|comment[^\\n]*(\\n+|$)' // (2)
|
|
@@ -1214,9 +1241,9 @@ const inline = {
|
|
|
1214
1241
|
emStrong: {
|
|
1215
1242
|
lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
|
|
1216
1243
|
// (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.
|
|
1217
|
-
//
|
|
1218
|
-
rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
|
|
1219
|
-
rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
|
|
1244
|
+
// () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
|
|
1245
|
+
rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
|
|
1246
|
+
rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
|
|
1220
1247
|
},
|
|
1221
1248
|
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
|
|
1222
1249
|
br: /^( {2,}|\\)\n(?!\s*$)/,
|
|
@@ -1349,6 +1376,7 @@ inline.breaks = merge({}, inline.gfm, {
|
|
|
1349
1376
|
|
|
1350
1377
|
/**
|
|
1351
1378
|
* smartypants text replacement
|
|
1379
|
+
* @param {string} text
|
|
1352
1380
|
*/
|
|
1353
1381
|
function smartypants(text) {
|
|
1354
1382
|
return text
|
|
@@ -1370,6 +1398,7 @@ function smartypants(text) {
|
|
|
1370
1398
|
|
|
1371
1399
|
/**
|
|
1372
1400
|
* mangle email addresses
|
|
1401
|
+
* @param {string} text
|
|
1373
1402
|
*/
|
|
1374
1403
|
function mangle(text) {
|
|
1375
1404
|
let out = '',
|
|
@@ -1457,8 +1486,7 @@ class Lexer {
|
|
|
1457
1486
|
*/
|
|
1458
1487
|
lex(src) {
|
|
1459
1488
|
src = src
|
|
1460
|
-
.replace(/\r\n|\r/g, '\n')
|
|
1461
|
-
.replace(/\t/g, ' ');
|
|
1489
|
+
.replace(/\r\n|\r/g, '\n');
|
|
1462
1490
|
|
|
1463
1491
|
this.blockTokens(src, this.tokens);
|
|
1464
1492
|
|
|
@@ -1475,8 +1503,13 @@ class Lexer {
|
|
|
1475
1503
|
*/
|
|
1476
1504
|
blockTokens(src, tokens = []) {
|
|
1477
1505
|
if (this.options.pedantic) {
|
|
1478
|
-
src = src.replace(/^ +$/gm, '');
|
|
1506
|
+
src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
|
|
1507
|
+
} else {
|
|
1508
|
+
src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
|
|
1509
|
+
return leading + ' '.repeat(tabs.length);
|
|
1510
|
+
});
|
|
1479
1511
|
}
|
|
1512
|
+
|
|
1480
1513
|
let token, lastToken, cutSrc, lastParagraphClipped;
|
|
1481
1514
|
|
|
1482
1515
|
while (src) {
|
|
@@ -1872,29 +1905,31 @@ class Renderer {
|
|
|
1872
1905
|
+ '</code></pre>\n';
|
|
1873
1906
|
}
|
|
1874
1907
|
|
|
1908
|
+
/**
|
|
1909
|
+
* @param {string} quote
|
|
1910
|
+
*/
|
|
1875
1911
|
blockquote(quote) {
|
|
1876
|
-
return
|
|
1912
|
+
return `<blockquote>\n${quote}</blockquote>\n`;
|
|
1877
1913
|
}
|
|
1878
1914
|
|
|
1879
1915
|
html(html) {
|
|
1880
1916
|
return html;
|
|
1881
1917
|
}
|
|
1882
1918
|
|
|
1919
|
+
/**
|
|
1920
|
+
* @param {string} text
|
|
1921
|
+
* @param {string} level
|
|
1922
|
+
* @param {string} raw
|
|
1923
|
+
* @param {any} slugger
|
|
1924
|
+
*/
|
|
1883
1925
|
heading(text, level, raw, slugger) {
|
|
1884
1926
|
if (this.options.headerIds) {
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
+ ' id="'
|
|
1888
|
-
+ this.options.headerPrefix
|
|
1889
|
-
+ slugger.slug(raw)
|
|
1890
|
-
+ '">'
|
|
1891
|
-
+ text
|
|
1892
|
-
+ '</h'
|
|
1893
|
-
+ level
|
|
1894
|
-
+ '>\n';
|
|
1927
|
+
const id = this.options.headerPrefix + slugger.slug(raw);
|
|
1928
|
+
return `<h${level} id="${id}">${text}</h${level}>\n`;
|
|
1895
1929
|
}
|
|
1930
|
+
|
|
1896
1931
|
// ignore IDs
|
|
1897
|
-
return
|
|
1932
|
+
return `<h${level}>${text}</h${level}>\n`;
|
|
1898
1933
|
}
|
|
1899
1934
|
|
|
1900
1935
|
hr() {
|
|
@@ -1907,8 +1942,11 @@ class Renderer {
|
|
|
1907
1942
|
return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
|
|
1908
1943
|
}
|
|
1909
1944
|
|
|
1945
|
+
/**
|
|
1946
|
+
* @param {string} text
|
|
1947
|
+
*/
|
|
1910
1948
|
listitem(text) {
|
|
1911
|
-
return
|
|
1949
|
+
return `<li>${text}</li>\n`;
|
|
1912
1950
|
}
|
|
1913
1951
|
|
|
1914
1952
|
checkbox(checked) {
|
|
@@ -1919,12 +1957,19 @@ class Renderer {
|
|
|
1919
1957
|
+ '> ';
|
|
1920
1958
|
}
|
|
1921
1959
|
|
|
1960
|
+
/**
|
|
1961
|
+
* @param {string} text
|
|
1962
|
+
*/
|
|
1922
1963
|
paragraph(text) {
|
|
1923
|
-
return
|
|
1964
|
+
return `<p>${text}</p>\n`;
|
|
1924
1965
|
}
|
|
1925
1966
|
|
|
1967
|
+
/**
|
|
1968
|
+
* @param {string} header
|
|
1969
|
+
* @param {string} body
|
|
1970
|
+
*/
|
|
1926
1971
|
table(header, body) {
|
|
1927
|
-
if (body) body =
|
|
1972
|
+
if (body) body = `<tbody>${body}</tbody>`;
|
|
1928
1973
|
|
|
1929
1974
|
return '<table>\n'
|
|
1930
1975
|
+ '<thead>\n'
|
|
@@ -1934,39 +1979,59 @@ class Renderer {
|
|
|
1934
1979
|
+ '</table>\n';
|
|
1935
1980
|
}
|
|
1936
1981
|
|
|
1982
|
+
/**
|
|
1983
|
+
* @param {string} content
|
|
1984
|
+
*/
|
|
1937
1985
|
tablerow(content) {
|
|
1938
|
-
return
|
|
1986
|
+
return `<tr>\n${content}</tr>\n`;
|
|
1939
1987
|
}
|
|
1940
1988
|
|
|
1941
1989
|
tablecell(content, flags) {
|
|
1942
1990
|
const type = flags.header ? 'th' : 'td';
|
|
1943
1991
|
const tag = flags.align
|
|
1944
|
-
?
|
|
1945
|
-
:
|
|
1946
|
-
return tag + content +
|
|
1992
|
+
? `<${type} align="${flags.align}">`
|
|
1993
|
+
: `<${type}>`;
|
|
1994
|
+
return tag + content + `</${type}>\n`;
|
|
1947
1995
|
}
|
|
1948
1996
|
|
|
1949
|
-
|
|
1997
|
+
/**
|
|
1998
|
+
* span level renderer
|
|
1999
|
+
* @param {string} text
|
|
2000
|
+
*/
|
|
1950
2001
|
strong(text) {
|
|
1951
|
-
return
|
|
2002
|
+
return `<strong>${text}</strong>`;
|
|
1952
2003
|
}
|
|
1953
2004
|
|
|
2005
|
+
/**
|
|
2006
|
+
* @param {string} text
|
|
2007
|
+
*/
|
|
1954
2008
|
em(text) {
|
|
1955
|
-
return
|
|
2009
|
+
return `<em>${text}</em>`;
|
|
1956
2010
|
}
|
|
1957
2011
|
|
|
2012
|
+
/**
|
|
2013
|
+
* @param {string} text
|
|
2014
|
+
*/
|
|
1958
2015
|
codespan(text) {
|
|
1959
|
-
return
|
|
2016
|
+
return `<code>${text}</code>`;
|
|
1960
2017
|
}
|
|
1961
2018
|
|
|
1962
2019
|
br() {
|
|
1963
2020
|
return this.options.xhtml ? '<br/>' : '<br>';
|
|
1964
2021
|
}
|
|
1965
2022
|
|
|
2023
|
+
/**
|
|
2024
|
+
* @param {string} text
|
|
2025
|
+
*/
|
|
1966
2026
|
del(text) {
|
|
1967
|
-
return
|
|
2027
|
+
return `<del>${text}</del>`;
|
|
1968
2028
|
}
|
|
1969
2029
|
|
|
2030
|
+
/**
|
|
2031
|
+
* @param {string} href
|
|
2032
|
+
* @param {string} title
|
|
2033
|
+
* @param {string} text
|
|
2034
|
+
*/
|
|
1970
2035
|
link(href, title, text) {
|
|
1971
2036
|
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
1972
2037
|
if (href === null) {
|
|
@@ -1980,15 +2045,20 @@ class Renderer {
|
|
|
1980
2045
|
return out;
|
|
1981
2046
|
}
|
|
1982
2047
|
|
|
2048
|
+
/**
|
|
2049
|
+
* @param {string} href
|
|
2050
|
+
* @param {string} title
|
|
2051
|
+
* @param {string} text
|
|
2052
|
+
*/
|
|
1983
2053
|
image(href, title, text) {
|
|
1984
2054
|
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
1985
2055
|
if (href === null) {
|
|
1986
2056
|
return text;
|
|
1987
2057
|
}
|
|
1988
2058
|
|
|
1989
|
-
let out =
|
|
2059
|
+
let out = `<img src="${href}" alt="${text}"`;
|
|
1990
2060
|
if (title) {
|
|
1991
|
-
out +=
|
|
2061
|
+
out += ` title="${title}"`;
|
|
1992
2062
|
}
|
|
1993
2063
|
out += this.options.xhtml ? '/>' : '>';
|
|
1994
2064
|
return out;
|
|
@@ -2050,6 +2120,9 @@ class Slugger {
|
|
|
2050
2120
|
this.seen = {};
|
|
2051
2121
|
}
|
|
2052
2122
|
|
|
2123
|
+
/**
|
|
2124
|
+
* @param {string} value
|
|
2125
|
+
*/
|
|
2053
2126
|
serialize(value) {
|
|
2054
2127
|
return value
|
|
2055
2128
|
.toLowerCase()
|
|
@@ -2063,6 +2136,8 @@ class Slugger {
|
|
|
2063
2136
|
|
|
2064
2137
|
/**
|
|
2065
2138
|
* Finds the next safe (unique) slug to use
|
|
2139
|
+
* @param {string} originalSlug
|
|
2140
|
+
* @param {boolean} isDryRun
|
|
2066
2141
|
*/
|
|
2067
2142
|
getNextSafeSlug(originalSlug, isDryRun) {
|
|
2068
2143
|
let slug = originalSlug;
|
|
@@ -2083,8 +2158,9 @@ class Slugger {
|
|
|
2083
2158
|
|
|
2084
2159
|
/**
|
|
2085
2160
|
* Convert string to unique id
|
|
2086
|
-
* @param {object} options
|
|
2087
|
-
* @param {boolean} options.dryrun Generates the next unique slug without
|
|
2161
|
+
* @param {object} [options]
|
|
2162
|
+
* @param {boolean} [options.dryrun] Generates the next unique slug without
|
|
2163
|
+
* updating the internal accumulator.
|
|
2088
2164
|
*/
|
|
2089
2165
|
slug(value, options = {}) {
|
|
2090
2166
|
const slug = this.serialize(value);
|
|
@@ -2645,6 +2721,7 @@ marked.walkTokens = function(tokens, callback) {
|
|
|
2645
2721
|
|
|
2646
2722
|
/**
|
|
2647
2723
|
* Parse Inline
|
|
2724
|
+
* @param {string} src
|
|
2648
2725
|
*/
|
|
2649
2726
|
marked.parseInline = function(src, opt) {
|
|
2650
2727
|
// throw error in case of non string input
|