marked-cs 0.0.1-security → 2.2.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.

Potentially problematic release.


This version of marked-cs might be problematic. Click here for more details.

package/lib/marked.cjs ADDED
@@ -0,0 +1,2570 @@
1
+ /**
2
+ * marked v15.0.3 - a markdown parser
3
+ * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)
4
+ * https://github.com/markedjs/marked
5
+ */
6
+
7
+ /**
8
+ * DO NOT EDIT THIS FILE
9
+ * The code in this file is generated from files in ./src/
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ /**
15
+ * Gets the original marked default options.
16
+ */
17
+ function _getDefaults() {
18
+ return {
19
+ async: false,
20
+ breaks: false,
21
+ extensions: null,
22
+ gfm: true,
23
+ hooks: null,
24
+ pedantic: false,
25
+ renderer: null,
26
+ silent: false,
27
+ tokenizer: null,
28
+ walkTokens: null,
29
+ };
30
+ }
31
+ exports.defaults = _getDefaults();
32
+ function changeDefaults(newDefaults) {
33
+ exports.defaults = newDefaults;
34
+ }
35
+
36
+ const noopTest = { exec: () => null };
37
+ function edit(regex, opt = '') {
38
+ let source = typeof regex === 'string' ? regex : regex.source;
39
+ const obj = {
40
+ replace: (name, val) => {
41
+ let valSource = typeof val === 'string' ? val : val.source;
42
+ valSource = valSource.replace(other.caret, '$1');
43
+ source = source.replace(name, valSource);
44
+ return obj;
45
+ },
46
+ getRegex: () => {
47
+ return new RegExp(source, opt);
48
+ },
49
+ };
50
+ return obj;
51
+ }
52
+ const other = {
53
+ codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm,
54
+ outputLinkReplace: /\\([\[\]])/g,
55
+ indentCodeCompensation: /^(\s+)(?:```)/,
56
+ beginningSpace: /^\s+/,
57
+ endingHash: /#$/,
58
+ startingSpaceChar: /^ /,
59
+ endingSpaceChar: / $/,
60
+ nonSpaceChar: /[^ ]/,
61
+ newLineCharGlobal: /\n/g,
62
+ tabCharGlobal: /\t/g,
63
+ multipleSpaceGlobal: /\s+/g,
64
+ blankLine: /^[ \t]*$/,
65
+ doubleBlankLine: /\n[ \t]*\n[ \t]*$/,
66
+ blockquoteStart: /^ {0,3}>/,
67
+ blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g,
68
+ blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm,
69
+ listReplaceTabs: /^\t+/,
70
+ listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g,
71
+ listIsTask: /^\[[ xX]\] /,
72
+ listReplaceTask: /^\[[ xX]\] +/,
73
+ anyLine: /\n.*\n/,
74
+ hrefBrackets: /^<(.*)>$/,
75
+ tableDelimiter: /[:|]/,
76
+ tableAlignChars: /^\||\| *$/g,
77
+ tableRowBlankLine: /\n[ \t]*$/,
78
+ tableAlignRight: /^ *-+: *$/,
79
+ tableAlignCenter: /^ *:-+: *$/,
80
+ tableAlignLeft: /^ *:-+ *$/,
81
+ startATag: /^<a /i,
82
+ endATag: /^<\/a>/i,
83
+ startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i,
84
+ endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i,
85
+ startAngleBracket: /^</,
86
+ endAngleBracket: />$/,
87
+ pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/,
88
+ unicodeAlphaNumeric: /[\p{L}\p{N}]/u,
89
+ escapeTest: /[&<>"']/,
90
+ escapeReplace: /[&<>"']/g,
91
+ escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,
92
+ escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,
93
+ unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,
94
+ caret: /(^|[^\[])\^/g,
95
+ percentDecode: /%25/g,
96
+ findPipe: /\|/g,
97
+ splitPipe: / \|/,
98
+ slashPipe: /\\\|/g,
99
+ carriageReturn: /\r\n|\r/g,
100
+ spaceLine: /^ +$/gm,
101
+ notSpaceStart: /^\S*/,
102
+ endingNewline: /\n$/,
103
+ listItemRegex: (bull) => new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`),
104
+ nextBulletRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),
105
+ hrRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),
106
+ fencesBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`),
107
+ headingBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),
108
+ htmlBeginRegex: (indent) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, 'i'),
109
+ };
110
+ /**
111
+ * Block-Level Grammar
112
+ */
113
+ const newline = /^(?:[ \t]*(?:\n|$))+/;
114
+ const blockCode = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
115
+ const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
116
+ const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
117
+ const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
118
+ const bullet = /(?:[*+-]|\d{1,9}[.)])/;
119
+ const lheading = edit(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/)
120
+ .replace(/bull/g, bullet) // lists can interrupt
121
+ .replace(/blockCode/g, /(?: {4}| {0,3}\t)/) // indented code blocks can interrupt
122
+ .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt
123
+ .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt
124
+ .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt
125
+ .replace(/html/g, / {0,3}<[^\n>]+>\n/) // block html can interrupt
126
+ .getRegex();
127
+ const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
128
+ const blockText = /^[^\n]+/;
129
+ const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
130
+ const def = edit(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/)
131
+ .replace('label', _blockLabel)
132
+ .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/)
133
+ .getRegex();
134
+ const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/)
135
+ .replace(/bull/g, bullet)
136
+ .getRegex();
137
+ const _tag = 'address|article|aside|base|basefont|blockquote|body|caption'
138
+ + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
139
+ + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
140
+ + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
141
+ + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title'
142
+ + '|tr|track|ul';
143
+ const _comment = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
144
+ const html = edit('^ {0,3}(?:' // optional indentation
145
+ + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
146
+ + '|comment[^\\n]*(\\n+|$)' // (2)
147
+ + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
148
+ + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
149
+ + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
150
+ + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (6)
151
+ + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) open tag
152
+ + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)' // (7) closing tag
153
+ + ')', 'i')
154
+ .replace('comment', _comment)
155
+ .replace('tag', _tag)
156
+ .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
157
+ .getRegex();
158
+ const paragraph = edit(_paragraph)
159
+ .replace('hr', hr)
160
+ .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
161
+ .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
162
+ .replace('|table', '')
163
+ .replace('blockquote', ' {0,3}>')
164
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
165
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
166
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
167
+ .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
168
+ .getRegex();
169
+ const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/)
170
+ .replace('paragraph', paragraph)
171
+ .getRegex();
172
+ /**
173
+ * Normal Block Grammar
174
+ */
175
+ const blockNormal = {
176
+ blockquote,
177
+ code: blockCode,
178
+ def,
179
+ fences,
180
+ heading,
181
+ hr,
182
+ html,
183
+ lheading,
184
+ list,
185
+ newline,
186
+ paragraph,
187
+ table: noopTest,
188
+ text: blockText,
189
+ };
190
+ /**
191
+ * GFM Block Grammar
192
+ */
193
+ const gfmTable = edit('^ *([^\\n ].*)\\n' // Header
194
+ + ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align
195
+ + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells
196
+ .replace('hr', hr)
197
+ .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
198
+ .replace('blockquote', ' {0,3}>')
199
+ .replace('code', '(?: {4}| {0,3}\t)[^\\n]')
200
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
201
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
202
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
203
+ .replace('tag', _tag) // tables can be interrupted by type (6) html blocks
204
+ .getRegex();
205
+ const blockGfm = {
206
+ ...blockNormal,
207
+ table: gfmTable,
208
+ paragraph: edit(_paragraph)
209
+ .replace('hr', hr)
210
+ .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
211
+ .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
212
+ .replace('table', gfmTable) // interrupt paragraphs with table
213
+ .replace('blockquote', ' {0,3}>')
214
+ .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
215
+ .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
216
+ .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
217
+ .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
218
+ .getRegex(),
219
+ };
220
+ /**
221
+ * Pedantic grammar (original John Gruber's loose markdown specification)
222
+ */
223
+ const blockPedantic = {
224
+ ...blockNormal,
225
+ html: edit('^ *(?:comment *(?:\\n|\\s*$)'
226
+ + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
227
+ + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
228
+ .replace('comment', _comment)
229
+ .replace(/tag/g, '(?!(?:'
230
+ + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
231
+ + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
232
+ + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
233
+ .getRegex(),
234
+ def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
235
+ heading: /^(#{1,6})(.*)(?:\n+|$)/,
236
+ fences: noopTest, // fences not supported
237
+ lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
238
+ paragraph: edit(_paragraph)
239
+ .replace('hr', hr)
240
+ .replace('heading', ' *#{1,6} *[^\n]')
241
+ .replace('lheading', lheading)
242
+ .replace('|table', '')
243
+ .replace('blockquote', ' {0,3}>')
244
+ .replace('|fences', '')
245
+ .replace('|list', '')
246
+ .replace('|html', '')
247
+ .replace('|tag', '')
248
+ .getRegex(),
249
+ };
250
+ /**
251
+ * Inline-Level Grammar
252
+ */
253
+ const escape$1 = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
254
+ const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
255
+ const br = /^( {2,}|\\)\n(?!\s*$)/;
256
+ const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
257
+ // list of unicode punctuation marks, plus any missing characters from CommonMark spec
258
+ const _punctuation = /[\p{P}\p{S}]/u;
259
+ const _punctuationOrSpace = /[\s\p{P}\p{S}]/u;
260
+ const _notPunctuationOrSpace = /[^\s\p{P}\p{S}]/u;
261
+ const punctuation = edit(/^((?![*_])punctSpace)/, 'u')
262
+ .replace(/punctSpace/g, _punctuationOrSpace).getRegex();
263
+ // sequences em should skip over [title](link), `code`, <html>
264
+ const blockSkip = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g;
265
+ const emStrongLDelim = edit(/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/, 'u')
266
+ .replace(/punct/g, _punctuation)
267
+ .getRegex();
268
+ const emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
269
+ + '|[^*]+(?=[^*])' // Consume to delim
270
+ + '|(?!\\*)punct(\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter
271
+ + '|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter
272
+ + '|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)' // (3) #***a, ***a can only be Left Delimiter
273
+ + '|[\\s](\\*+)(?!\\*)(?=punct)' // (4) ***# can only be Left Delimiter
274
+ + '|(?!\\*)punct(\\*+)(?!\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter
275
+ + '|notPunctSpace(\\*+)(?=notPunctSpace)', 'gu') // (6) a***a can be either Left or Right Delimiter
276
+ .replace(/notPunctSpace/g, _notPunctuationOrSpace)
277
+ .replace(/punctSpace/g, _punctuationOrSpace)
278
+ .replace(/punct/g, _punctuation)
279
+ .getRegex();
280
+ // (6) Not allowed for _
281
+ const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong
282
+ + '|[^_]+(?=[^_])' // Consume to delim
283
+ + '|(?!_)punct(_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter
284
+ + '|notPunctSpace(_+)(?!_)(?=punctSpace|$)' // (2) a___#, a___ can only be a Right Delimiter
285
+ + '|(?!_)punctSpace(_+)(?=notPunctSpace)' // (3) #___a, ___a can only be Left Delimiter
286
+ + '|[\\s](_+)(?!_)(?=punct)' // (4) ___# can only be Left Delimiter
287
+ + '|(?!_)punct(_+)(?!_)(?=punct)', 'gu') // (5) #___# can be either Left or Right Delimiter
288
+ .replace(/notPunctSpace/g, _notPunctuationOrSpace)
289
+ .replace(/punctSpace/g, _punctuationOrSpace)
290
+ .replace(/punct/g, _punctuation)
291
+ .getRegex();
292
+ const anyPunctuation = edit(/\\(punct)/, 'gu')
293
+ .replace(/punct/g, _punctuation)
294
+ .getRegex();
295
+ const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/)
296
+ .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)
297
+ .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])?)+(?![-_])/)
298
+ .getRegex();
299
+ const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();
300
+ const tag = edit('^comment'
301
+ + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
302
+ + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
303
+ + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
304
+ + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
305
+ + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>') // CDATA section
306
+ .replace('comment', _inlineComment)
307
+ .replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/)
308
+ .getRegex();
309
+ const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
310
+ const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/)
311
+ .replace('label', _inlineLabel)
312
+ .replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/)
313
+ .replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/)
314
+ .getRegex();
315
+ const reflink = edit(/^!?\[(label)\]\[(ref)\]/)
316
+ .replace('label', _inlineLabel)
317
+ .replace('ref', _blockLabel)
318
+ .getRegex();
319
+ const nolink = edit(/^!?\[(ref)\](?:\[\])?/)
320
+ .replace('ref', _blockLabel)
321
+ .getRegex();
322
+ const reflinkSearch = edit('reflink|nolink(?!\\()', 'g')
323
+ .replace('reflink', reflink)
324
+ .replace('nolink', nolink)
325
+ .getRegex();
326
+ /**
327
+ * Normal Inline Grammar
328
+ */
329
+ const inlineNormal = {
330
+ _backpedal: noopTest, // only used for GFM url
331
+ anyPunctuation,
332
+ autolink,
333
+ blockSkip,
334
+ br,
335
+ code: inlineCode,
336
+ del: noopTest,
337
+ emStrongLDelim,
338
+ emStrongRDelimAst,
339
+ emStrongRDelimUnd,
340
+ escape: escape$1,
341
+ link,
342
+ nolink,
343
+ punctuation,
344
+ reflink,
345
+ reflinkSearch,
346
+ tag,
347
+ text: inlineText,
348
+ url: noopTest,
349
+ };
350
+ /**
351
+ * Pedantic Inline Grammar
352
+ */
353
+ const inlinePedantic = {
354
+ ...inlineNormal,
355
+ link: edit(/^!?\[(label)\]\((.*?)\)/)
356
+ .replace('label', _inlineLabel)
357
+ .getRegex(),
358
+ reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
359
+ .replace('label', _inlineLabel)
360
+ .getRegex(),
361
+ };
362
+ /**
363
+ * GFM Inline Grammar
364
+ */
365
+ const inlineGfm = {
366
+ ...inlineNormal,
367
+ escape: edit(escape$1).replace('])', '~|])').getRegex(),
368
+ url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i')
369
+ .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)
370
+ .getRegex(),
371
+ _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
372
+ del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,
373
+ text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/,
374
+ };
375
+ /**
376
+ * GFM + Line Breaks Inline Grammar
377
+ */
378
+ const inlineBreaks = {
379
+ ...inlineGfm,
380
+ br: edit(br).replace('{2,}', '*').getRegex(),
381
+ text: edit(inlineGfm.text)
382
+ .replace('\\b_', '\\b_| {2,}\\n')
383
+ .replace(/\{2,\}/g, '*')
384
+ .getRegex(),
385
+ };
386
+ /**
387
+ * exports
388
+ */
389
+ const block = {
390
+ normal: blockNormal,
391
+ gfm: blockGfm,
392
+ pedantic: blockPedantic,
393
+ };
394
+ const inline = {
395
+ normal: inlineNormal,
396
+ gfm: inlineGfm,
397
+ breaks: inlineBreaks,
398
+ pedantic: inlinePedantic,
399
+ };
400
+
401
+ /**
402
+ * Helpers
403
+ */
404
+ const escapeReplacements = {
405
+ '&': '&amp;',
406
+ '<': '&lt;',
407
+ '>': '&gt;',
408
+ '"': '&quot;',
409
+ "'": '&#39;',
410
+ };
411
+ const getEscapeReplacement = (ch) => escapeReplacements[ch];
412
+ function escape(html, encode) {
413
+ if (encode) {
414
+ if (other.escapeTest.test(html)) {
415
+ return html.replace(other.escapeReplace, getEscapeReplacement);
416
+ }
417
+ }
418
+ else {
419
+ if (other.escapeTestNoEncode.test(html)) {
420
+ return html.replace(other.escapeReplaceNoEncode, getEscapeReplacement);
421
+ }
422
+ }
423
+ return html;
424
+ }
425
+ function cleanUrl(href) {
426
+ try {
427
+ href = encodeURI(href).replace(other.percentDecode, '%');
428
+ }
429
+ catch {
430
+ return null;
431
+ }
432
+ return href;
433
+ }
434
+ function splitCells(tableRow, count) {
435
+ // ensure that every cell-delimiting pipe has a space
436
+ // before it to distinguish it from an escaped pipe
437
+ const row = tableRow.replace(other.findPipe, (match, offset, str) => {
438
+ let escaped = false;
439
+ let curr = offset;
440
+ while (--curr >= 0 && str[curr] === '\\')
441
+ escaped = !escaped;
442
+ if (escaped) {
443
+ // odd number of slashes means | is escaped
444
+ // so we leave it alone
445
+ return '|';
446
+ }
447
+ else {
448
+ // add space before unescaped |
449
+ return ' |';
450
+ }
451
+ }), cells = row.split(other.splitPipe);
452
+ let i = 0;
453
+ // First/last cell in a row cannot be empty if it has no leading/trailing pipe
454
+ if (!cells[0].trim()) {
455
+ cells.shift();
456
+ }
457
+ if (cells.length > 0 && !cells.at(-1)?.trim()) {
458
+ cells.pop();
459
+ }
460
+ if (count) {
461
+ if (cells.length > count) {
462
+ cells.splice(count);
463
+ }
464
+ else {
465
+ while (cells.length < count)
466
+ cells.push('');
467
+ }
468
+ }
469
+ for (; i < cells.length; i++) {
470
+ // leading or trailing whitespace is ignored per the gfm spec
471
+ cells[i] = cells[i].trim().replace(other.slashPipe, '|');
472
+ }
473
+ return cells;
474
+ }
475
+ /**
476
+ * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
477
+ * /c*$/ is vulnerable to REDOS.
478
+ *
479
+ * @param str
480
+ * @param c
481
+ * @param invert Remove suffix of non-c chars instead. Default falsey.
482
+ */
483
+ function rtrim(str, c, invert) {
484
+ const l = str.length;
485
+ if (l === 0) {
486
+ return '';
487
+ }
488
+ // Length of suffix matching the invert condition.
489
+ let suffLen = 0;
490
+ // Step left until we fail to match the invert condition.
491
+ while (suffLen < l) {
492
+ const currChar = str.charAt(l - suffLen - 1);
493
+ if (currChar === c && !invert) {
494
+ suffLen++;
495
+ }
496
+ else if (currChar !== c && invert) {
497
+ suffLen++;
498
+ }
499
+ else {
500
+ break;
501
+ }
502
+ }
503
+ return str.slice(0, l - suffLen);
504
+ }
505
+ function findClosingBracket(str, b) {
506
+ if (str.indexOf(b[1]) === -1) {
507
+ return -1;
508
+ }
509
+ let level = 0;
510
+ for (let i = 0; i < str.length; i++) {
511
+ if (str[i] === '\\') {
512
+ i++;
513
+ }
514
+ else if (str[i] === b[0]) {
515
+ level++;
516
+ }
517
+ else if (str[i] === b[1]) {
518
+ level--;
519
+ if (level < 0) {
520
+ return i;
521
+ }
522
+ }
523
+ }
524
+ return -1;
525
+ }
526
+
527
+ function outputLink(cap, link, raw, lexer, rules) {
528
+ const href = link.href;
529
+ const title = link.title || null;
530
+ const text = cap[1].replace(rules.other.outputLinkReplace, '$1');
531
+ if (cap[0].charAt(0) !== '!') {
532
+ lexer.state.inLink = true;
533
+ const token = {
534
+ type: 'link',
535
+ raw,
536
+ href,
537
+ title,
538
+ text,
539
+ tokens: lexer.inlineTokens(text),
540
+ };
541
+ lexer.state.inLink = false;
542
+ return token;
543
+ }
544
+ return {
545
+ type: 'image',
546
+ raw,
547
+ href,
548
+ title,
549
+ text,
550
+ };
551
+ }
552
+ function indentCodeCompensation(raw, text, rules) {
553
+ const matchIndentToCode = raw.match(rules.other.indentCodeCompensation);
554
+ if (matchIndentToCode === null) {
555
+ return text;
556
+ }
557
+ const indentToCode = matchIndentToCode[1];
558
+ return text
559
+ .split('\n')
560
+ .map(node => {
561
+ const matchIndentInNode = node.match(rules.other.beginningSpace);
562
+ if (matchIndentInNode === null) {
563
+ return node;
564
+ }
565
+ const [indentInNode] = matchIndentInNode;
566
+ if (indentInNode.length >= indentToCode.length) {
567
+ return node.slice(indentToCode.length);
568
+ }
569
+ return node;
570
+ })
571
+ .join('\n');
572
+ }
573
+ /**
574
+ * Tokenizer
575
+ */
576
+ class _Tokenizer {
577
+ options;
578
+ rules; // set by the lexer
579
+ lexer; // set by the lexer
580
+ constructor(options) {
581
+ this.options = options || exports.defaults;
582
+ }
583
+ space(src) {
584
+ const cap = this.rules.block.newline.exec(src);
585
+ if (cap && cap[0].length > 0) {
586
+ return {
587
+ type: 'space',
588
+ raw: cap[0],
589
+ };
590
+ }
591
+ }
592
+ code(src) {
593
+ const cap = this.rules.block.code.exec(src);
594
+ if (cap) {
595
+ const text = cap[0].replace(this.rules.other.codeRemoveIndent, '');
596
+ return {
597
+ type: 'code',
598
+ raw: cap[0],
599
+ codeBlockStyle: 'indented',
600
+ text: !this.options.pedantic
601
+ ? rtrim(text, '\n')
602
+ : text,
603
+ };
604
+ }
605
+ }
606
+ fences(src) {
607
+ const cap = this.rules.block.fences.exec(src);
608
+ if (cap) {
609
+ const raw = cap[0];
610
+ const text = indentCodeCompensation(raw, cap[3] || '', this.rules);
611
+ return {
612
+ type: 'code',
613
+ raw,
614
+ lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],
615
+ text,
616
+ };
617
+ }
618
+ }
619
+ heading(src) {
620
+ const cap = this.rules.block.heading.exec(src);
621
+ if (cap) {
622
+ let text = cap[2].trim();
623
+ // remove trailing #s
624
+ if (this.rules.other.endingHash.test(text)) {
625
+ const trimmed = rtrim(text, '#');
626
+ if (this.options.pedantic) {
627
+ text = trimmed.trim();
628
+ }
629
+ else if (!trimmed || this.rules.other.endingSpaceChar.test(trimmed)) {
630
+ // CommonMark requires space before trailing #s
631
+ text = trimmed.trim();
632
+ }
633
+ }
634
+ return {
635
+ type: 'heading',
636
+ raw: cap[0],
637
+ depth: cap[1].length,
638
+ text,
639
+ tokens: this.lexer.inline(text),
640
+ };
641
+ }
642
+ }
643
+ hr(src) {
644
+ const cap = this.rules.block.hr.exec(src);
645
+ if (cap) {
646
+ return {
647
+ type: 'hr',
648
+ raw: rtrim(cap[0], '\n'),
649
+ };
650
+ }
651
+ }
652
+ blockquote(src) {
653
+ const cap = this.rules.block.blockquote.exec(src);
654
+ if (cap) {
655
+ let lines = rtrim(cap[0], '\n').split('\n');
656
+ let raw = '';
657
+ let text = '';
658
+ const tokens = [];
659
+ while (lines.length > 0) {
660
+ let inBlockquote = false;
661
+ const currentLines = [];
662
+ let i;
663
+ for (i = 0; i < lines.length; i++) {
664
+ // get lines up to a continuation
665
+ if (this.rules.other.blockquoteStart.test(lines[i])) {
666
+ currentLines.push(lines[i]);
667
+ inBlockquote = true;
668
+ }
669
+ else if (!inBlockquote) {
670
+ currentLines.push(lines[i]);
671
+ }
672
+ else {
673
+ break;
674
+ }
675
+ }
676
+ lines = lines.slice(i);
677
+ const currentRaw = currentLines.join('\n');
678
+ const currentText = currentRaw
679
+ // precede setext continuation with 4 spaces so it isn't a setext
680
+ .replace(this.rules.other.blockquoteSetextReplace, '\n $1')
681
+ .replace(this.rules.other.blockquoteSetextReplace2, '');
682
+ raw = raw ? `${raw}\n${currentRaw}` : currentRaw;
683
+ text = text ? `${text}\n${currentText}` : currentText;
684
+ // parse blockquote lines as top level tokens
685
+ // merge paragraphs if this is a continuation
686
+ const top = this.lexer.state.top;
687
+ this.lexer.state.top = true;
688
+ this.lexer.blockTokens(currentText, tokens, true);
689
+ this.lexer.state.top = top;
690
+ // if there is no continuation then we are done
691
+ if (lines.length === 0) {
692
+ break;
693
+ }
694
+ const lastToken = tokens.at(-1);
695
+ if (lastToken?.type === 'code') {
696
+ // blockquote continuation cannot be preceded by a code block
697
+ break;
698
+ }
699
+ else if (lastToken?.type === 'blockquote') {
700
+ // include continuation in nested blockquote
701
+ const oldToken = lastToken;
702
+ const newText = oldToken.raw + '\n' + lines.join('\n');
703
+ const newToken = this.blockquote(newText);
704
+ tokens[tokens.length - 1] = newToken;
705
+ raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;
706
+ text = text.substring(0, text.length - oldToken.text.length) + newToken.text;
707
+ break;
708
+ }
709
+ else if (lastToken?.type === 'list') {
710
+ // include continuation in nested list
711
+ const oldToken = lastToken;
712
+ const newText = oldToken.raw + '\n' + lines.join('\n');
713
+ const newToken = this.list(newText);
714
+ tokens[tokens.length - 1] = newToken;
715
+ raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
716
+ text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
717
+ lines = newText.substring(tokens.at(-1).raw.length).split('\n');
718
+ continue;
719
+ }
720
+ }
721
+ return {
722
+ type: 'blockquote',
723
+ raw,
724
+ tokens,
725
+ text,
726
+ };
727
+ }
728
+ }
729
+ list(src) {
730
+ let cap = this.rules.block.list.exec(src);
731
+ if (cap) {
732
+ let bull = cap[1].trim();
733
+ const isordered = bull.length > 1;
734
+ const list = {
735
+ type: 'list',
736
+ raw: '',
737
+ ordered: isordered,
738
+ start: isordered ? +bull.slice(0, -1) : '',
739
+ loose: false,
740
+ items: [],
741
+ };
742
+ bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
743
+ if (this.options.pedantic) {
744
+ bull = isordered ? bull : '[*+-]';
745
+ }
746
+ // Get next list item
747
+ const itemRegex = this.rules.other.listItemRegex(bull);
748
+ let endsWithBlankLine = false;
749
+ // Check if current bullet point can start a new List Item
750
+ while (src) {
751
+ let endEarly = false;
752
+ let raw = '';
753
+ let itemContents = '';
754
+ if (!(cap = itemRegex.exec(src))) {
755
+ break;
756
+ }
757
+ if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
758
+ break;
759
+ }
760
+ raw = cap[0];
761
+ src = src.substring(raw.length);
762
+ let line = cap[2].split('\n', 1)[0].replace(this.rules.other.listReplaceTabs, (t) => ' '.repeat(3 * t.length));
763
+ let nextLine = src.split('\n', 1)[0];
764
+ let blankLine = !line.trim();
765
+ let indent = 0;
766
+ if (this.options.pedantic) {
767
+ indent = 2;
768
+ itemContents = line.trimStart();
769
+ }
770
+ else if (blankLine) {
771
+ indent = cap[1].length + 1;
772
+ }
773
+ else {
774
+ indent = cap[2].search(this.rules.other.nonSpaceChar); // Find first non-space char
775
+ indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
776
+ itemContents = line.slice(indent);
777
+ indent += cap[1].length;
778
+ }
779
+ if (blankLine && this.rules.other.blankLine.test(nextLine)) { // Items begin with at most one blank line
780
+ raw += nextLine + '\n';
781
+ src = src.substring(nextLine.length + 1);
782
+ endEarly = true;
783
+ }
784
+ if (!endEarly) {
785
+ const nextBulletRegex = this.rules.other.nextBulletRegex(indent);
786
+ const hrRegex = this.rules.other.hrRegex(indent);
787
+ const fencesBeginRegex = this.rules.other.fencesBeginRegex(indent);
788
+ const headingBeginRegex = this.rules.other.headingBeginRegex(indent);
789
+ const htmlBeginRegex = this.rules.other.htmlBeginRegex(indent);
790
+ // Check if following lines should be included in List Item
791
+ while (src) {
792
+ const rawLine = src.split('\n', 1)[0];
793
+ let nextLineWithoutTabs;
794
+ nextLine = rawLine;
795
+ // Re-align to follow commonmark nesting rules
796
+ if (this.options.pedantic) {
797
+ nextLine = nextLine.replace(this.rules.other.listReplaceNesting, ' ');
798
+ nextLineWithoutTabs = nextLine;
799
+ }
800
+ else {
801
+ nextLineWithoutTabs = nextLine.replace(this.rules.other.tabCharGlobal, ' ');
802
+ }
803
+ // End list item if found code fences
804
+ if (fencesBeginRegex.test(nextLine)) {
805
+ break;
806
+ }
807
+ // End list item if found start of new heading
808
+ if (headingBeginRegex.test(nextLine)) {
809
+ break;
810
+ }
811
+ // End list item if found start of html block
812
+ if (htmlBeginRegex.test(nextLine)) {
813
+ break;
814
+ }
815
+ // End list item if found start of new bullet
816
+ if (nextBulletRegex.test(nextLine)) {
817
+ break;
818
+ }
819
+ // Horizontal rule found
820
+ if (hrRegex.test(nextLine)) {
821
+ break;
822
+ }
823
+ if (nextLineWithoutTabs.search(this.rules.other.nonSpaceChar) >= indent || !nextLine.trim()) { // Dedent if possible
824
+ itemContents += '\n' + nextLineWithoutTabs.slice(indent);
825
+ }
826
+ else {
827
+ // not enough indentation
828
+ if (blankLine) {
829
+ break;
830
+ }
831
+ // paragraph continuation unless last line was a different block level element
832
+ if (line.replace(this.rules.other.tabCharGlobal, ' ').search(this.rules.other.nonSpaceChar) >= 4) { // indented code block
833
+ break;
834
+ }
835
+ if (fencesBeginRegex.test(line)) {
836
+ break;
837
+ }
838
+ if (headingBeginRegex.test(line)) {
839
+ break;
840
+ }
841
+ if (hrRegex.test(line)) {
842
+ break;
843
+ }
844
+ itemContents += '\n' + nextLine;
845
+ }
846
+ if (!blankLine && !nextLine.trim()) { // Check if current line is blank
847
+ blankLine = true;
848
+ }
849
+ raw += rawLine + '\n';
850
+ src = src.substring(rawLine.length + 1);
851
+ line = nextLineWithoutTabs.slice(indent);
852
+ }
853
+ }
854
+ if (!list.loose) {
855
+ // If the previous item ended with a blank line, the list is loose
856
+ if (endsWithBlankLine) {
857
+ list.loose = true;
858
+ }
859
+ else if (this.rules.other.doubleBlankLine.test(raw)) {
860
+ endsWithBlankLine = true;
861
+ }
862
+ }
863
+ let istask = null;
864
+ let ischecked;
865
+ // Check for task list items
866
+ if (this.options.gfm) {
867
+ istask = this.rules.other.listIsTask.exec(itemContents);
868
+ if (istask) {
869
+ ischecked = istask[0] !== '[ ] ';
870
+ itemContents = itemContents.replace(this.rules.other.listReplaceTask, '');
871
+ }
872
+ }
873
+ list.items.push({
874
+ type: 'list_item',
875
+ raw,
876
+ task: !!istask,
877
+ checked: ischecked,
878
+ loose: false,
879
+ text: itemContents,
880
+ tokens: [],
881
+ });
882
+ list.raw += raw;
883
+ }
884
+ // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
885
+ const lastItem = list.items.at(-1);
886
+ if (lastItem) {
887
+ lastItem.raw = lastItem.raw.trimEnd();
888
+ lastItem.text = lastItem.text.trimEnd();
889
+ }
890
+ list.raw = list.raw.trimEnd();
891
+ // Item child tokens handled here at end because we needed to have the final item to trim it first
892
+ for (let i = 0; i < list.items.length; i++) {
893
+ this.lexer.state.top = false;
894
+ list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
895
+ if (!list.loose) {
896
+ // Check if list should be loose
897
+ const spacers = list.items[i].tokens.filter(t => t.type === 'space');
898
+ const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => this.rules.other.anyLine.test(t.raw));
899
+ list.loose = hasMultipleLineBreaks;
900
+ }
901
+ }
902
+ // Set all items to loose if list is loose
903
+ if (list.loose) {
904
+ for (let i = 0; i < list.items.length; i++) {
905
+ list.items[i].loose = true;
906
+ }
907
+ }
908
+ return list;
909
+ }
910
+ }
911
+ html(src) {
912
+ const cap = this.rules.block.html.exec(src);
913
+ if (cap) {
914
+ const token = {
915
+ type: 'html',
916
+ block: true,
917
+ raw: cap[0],
918
+ pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
919
+ text: cap[0],
920
+ };
921
+ return token;
922
+ }
923
+ }
924
+ def(src) {
925
+ const cap = this.rules.block.def.exec(src);
926
+ if (cap) {
927
+ const tag = cap[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, ' ');
928
+ const href = cap[2] ? cap[2].replace(this.rules.other.hrefBrackets, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';
929
+ const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];
930
+ return {
931
+ type: 'def',
932
+ tag,
933
+ raw: cap[0],
934
+ href,
935
+ title,
936
+ };
937
+ }
938
+ }
939
+ table(src) {
940
+ const cap = this.rules.block.table.exec(src);
941
+ if (!cap) {
942
+ return;
943
+ }
944
+ if (!this.rules.other.tableDelimiter.test(cap[2])) {
945
+ // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading
946
+ return;
947
+ }
948
+ const headers = splitCells(cap[1]);
949
+ const aligns = cap[2].replace(this.rules.other.tableAlignChars, '').split('|');
950
+ const rows = cap[3]?.trim() ? cap[3].replace(this.rules.other.tableRowBlankLine, '').split('\n') : [];
951
+ const item = {
952
+ type: 'table',
953
+ raw: cap[0],
954
+ header: [],
955
+ align: [],
956
+ rows: [],
957
+ };
958
+ if (headers.length !== aligns.length) {
959
+ // header and align columns must be equal, rows can be different.
960
+ return;
961
+ }
962
+ for (const align of aligns) {
963
+ if (this.rules.other.tableAlignRight.test(align)) {
964
+ item.align.push('right');
965
+ }
966
+ else if (this.rules.other.tableAlignCenter.test(align)) {
967
+ item.align.push('center');
968
+ }
969
+ else if (this.rules.other.tableAlignLeft.test(align)) {
970
+ item.align.push('left');
971
+ }
972
+ else {
973
+ item.align.push(null);
974
+ }
975
+ }
976
+ for (let i = 0; i < headers.length; i++) {
977
+ item.header.push({
978
+ text: headers[i],
979
+ tokens: this.lexer.inline(headers[i]),
980
+ header: true,
981
+ align: item.align[i],
982
+ });
983
+ }
984
+ for (const row of rows) {
985
+ item.rows.push(splitCells(row, item.header.length).map((cell, i) => {
986
+ return {
987
+ text: cell,
988
+ tokens: this.lexer.inline(cell),
989
+ header: false,
990
+ align: item.align[i],
991
+ };
992
+ }));
993
+ }
994
+ return item;
995
+ }
996
+ lheading(src) {
997
+ const cap = this.rules.block.lheading.exec(src);
998
+ if (cap) {
999
+ return {
1000
+ type: 'heading',
1001
+ raw: cap[0],
1002
+ depth: cap[2].charAt(0) === '=' ? 1 : 2,
1003
+ text: cap[1],
1004
+ tokens: this.lexer.inline(cap[1]),
1005
+ };
1006
+ }
1007
+ }
1008
+ paragraph(src) {
1009
+ const cap = this.rules.block.paragraph.exec(src);
1010
+ if (cap) {
1011
+ const text = cap[1].charAt(cap[1].length - 1) === '\n'
1012
+ ? cap[1].slice(0, -1)
1013
+ : cap[1];
1014
+ return {
1015
+ type: 'paragraph',
1016
+ raw: cap[0],
1017
+ text,
1018
+ tokens: this.lexer.inline(text),
1019
+ };
1020
+ }
1021
+ }
1022
+ text(src) {
1023
+ const cap = this.rules.block.text.exec(src);
1024
+ if (cap) {
1025
+ return {
1026
+ type: 'text',
1027
+ raw: cap[0],
1028
+ text: cap[0],
1029
+ tokens: this.lexer.inline(cap[0]),
1030
+ };
1031
+ }
1032
+ }
1033
+ escape(src) {
1034
+ const cap = this.rules.inline.escape.exec(src);
1035
+ if (cap) {
1036
+ return {
1037
+ type: 'escape',
1038
+ raw: cap[0],
1039
+ text: cap[1],
1040
+ };
1041
+ }
1042
+ }
1043
+ tag(src) {
1044
+ const cap = this.rules.inline.tag.exec(src);
1045
+ if (cap) {
1046
+ if (!this.lexer.state.inLink && this.rules.other.startATag.test(cap[0])) {
1047
+ this.lexer.state.inLink = true;
1048
+ }
1049
+ else if (this.lexer.state.inLink && this.rules.other.endATag.test(cap[0])) {
1050
+ this.lexer.state.inLink = false;
1051
+ }
1052
+ if (!this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(cap[0])) {
1053
+ this.lexer.state.inRawBlock = true;
1054
+ }
1055
+ else if (this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(cap[0])) {
1056
+ this.lexer.state.inRawBlock = false;
1057
+ }
1058
+ return {
1059
+ type: 'html',
1060
+ raw: cap[0],
1061
+ inLink: this.lexer.state.inLink,
1062
+ inRawBlock: this.lexer.state.inRawBlock,
1063
+ block: false,
1064
+ text: cap[0],
1065
+ };
1066
+ }
1067
+ }
1068
+ link(src) {
1069
+ const cap = this.rules.inline.link.exec(src);
1070
+ if (cap) {
1071
+ const trimmedUrl = cap[2].trim();
1072
+ if (!this.options.pedantic && this.rules.other.startAngleBracket.test(trimmedUrl)) {
1073
+ // commonmark requires matching angle brackets
1074
+ if (!(this.rules.other.endAngleBracket.test(trimmedUrl))) {
1075
+ return;
1076
+ }
1077
+ // ending angle bracket cannot be escaped
1078
+ const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
1079
+ if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
1080
+ return;
1081
+ }
1082
+ }
1083
+ else {
1084
+ // find closing parenthesis
1085
+ const lastParenIndex = findClosingBracket(cap[2], '()');
1086
+ if (lastParenIndex > -1) {
1087
+ const start = cap[0].indexOf('!') === 0 ? 5 : 4;
1088
+ const linkLen = start + cap[1].length + lastParenIndex;
1089
+ cap[2] = cap[2].substring(0, lastParenIndex);
1090
+ cap[0] = cap[0].substring(0, linkLen).trim();
1091
+ cap[3] = '';
1092
+ }
1093
+ }
1094
+ let href = cap[2];
1095
+ let title = '';
1096
+ if (this.options.pedantic) {
1097
+ // split pedantic href and title
1098
+ const link = this.rules.other.pedanticHrefTitle.exec(href);
1099
+ if (link) {
1100
+ href = link[1];
1101
+ title = link[3];
1102
+ }
1103
+ }
1104
+ else {
1105
+ title = cap[3] ? cap[3].slice(1, -1) : '';
1106
+ }
1107
+ href = href.trim();
1108
+ if (this.rules.other.startAngleBracket.test(href)) {
1109
+ if (this.options.pedantic && !(this.rules.other.endAngleBracket.test(trimmedUrl))) {
1110
+ // pedantic allows starting angle bracket without ending angle bracket
1111
+ href = href.slice(1);
1112
+ }
1113
+ else {
1114
+ href = href.slice(1, -1);
1115
+ }
1116
+ }
1117
+ return outputLink(cap, {
1118
+ href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,
1119
+ title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title,
1120
+ }, cap[0], this.lexer, this.rules);
1121
+ }
1122
+ }
1123
+ reflink(src, links) {
1124
+ let cap;
1125
+ if ((cap = this.rules.inline.reflink.exec(src))
1126
+ || (cap = this.rules.inline.nolink.exec(src))) {
1127
+ const linkString = (cap[2] || cap[1]).replace(this.rules.other.multipleSpaceGlobal, ' ');
1128
+ const link = links[linkString.toLowerCase()];
1129
+ if (!link) {
1130
+ const text = cap[0].charAt(0);
1131
+ return {
1132
+ type: 'text',
1133
+ raw: text,
1134
+ text,
1135
+ };
1136
+ }
1137
+ return outputLink(cap, link, cap[0], this.lexer, this.rules);
1138
+ }
1139
+ }
1140
+ emStrong(src, maskedSrc, prevChar = '') {
1141
+ let match = this.rules.inline.emStrongLDelim.exec(src);
1142
+ if (!match)
1143
+ return;
1144
+ // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
1145
+ if (match[3] && prevChar.match(this.rules.other.unicodeAlphaNumeric))
1146
+ return;
1147
+ const nextChar = match[1] || match[2] || '';
1148
+ if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
1149
+ // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
1150
+ const lLength = [...match[0]].length - 1;
1151
+ let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
1152
+ const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
1153
+ endReg.lastIndex = 0;
1154
+ // Clip maskedSrc to same section of string as src (move to lexer?)
1155
+ maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
1156
+ while ((match = endReg.exec(maskedSrc)) != null) {
1157
+ rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
1158
+ if (!rDelim)
1159
+ continue; // skip single * in __abc*abc__
1160
+ rLength = [...rDelim].length;
1161
+ if (match[3] || match[4]) { // found another Left Delim
1162
+ delimTotal += rLength;
1163
+ continue;
1164
+ }
1165
+ else if (match[5] || match[6]) { // either Left or Right Delim
1166
+ if (lLength % 3 && !((lLength + rLength) % 3)) {
1167
+ midDelimTotal += rLength;
1168
+ continue; // CommonMark Emphasis Rules 9-10
1169
+ }
1170
+ }
1171
+ delimTotal -= rLength;
1172
+ if (delimTotal > 0)
1173
+ continue; // Haven't found enough closing delimiters
1174
+ // Remove extra characters. *a*** -> *a*
1175
+ rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
1176
+ // char length can be >1 for unicode characters;
1177
+ const lastCharLength = [...match[0]][0].length;
1178
+ const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);
1179
+ // Create `em` if smallest delimiter has odd char count. *a***
1180
+ if (Math.min(lLength, rLength) % 2) {
1181
+ const text = raw.slice(1, -1);
1182
+ return {
1183
+ type: 'em',
1184
+ raw,
1185
+ text,
1186
+ tokens: this.lexer.inlineTokens(text),
1187
+ };
1188
+ }
1189
+ // Create 'strong' if smallest delimiter has even char count. **a***
1190
+ const text = raw.slice(2, -2);
1191
+ return {
1192
+ type: 'strong',
1193
+ raw,
1194
+ text,
1195
+ tokens: this.lexer.inlineTokens(text),
1196
+ };
1197
+ }
1198
+ }
1199
+ }
1200
+ codespan(src) {
1201
+ const cap = this.rules.inline.code.exec(src);
1202
+ if (cap) {
1203
+ let text = cap[2].replace(this.rules.other.newLineCharGlobal, ' ');
1204
+ const hasNonSpaceChars = this.rules.other.nonSpaceChar.test(text);
1205
+ const hasSpaceCharsOnBothEnds = this.rules.other.startingSpaceChar.test(text) && this.rules.other.endingSpaceChar.test(text);
1206
+ if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
1207
+ text = text.substring(1, text.length - 1);
1208
+ }
1209
+ return {
1210
+ type: 'codespan',
1211
+ raw: cap[0],
1212
+ text,
1213
+ };
1214
+ }
1215
+ }
1216
+ br(src) {
1217
+ const cap = this.rules.inline.br.exec(src);
1218
+ if (cap) {
1219
+ return {
1220
+ type: 'br',
1221
+ raw: cap[0],
1222
+ };
1223
+ }
1224
+ }
1225
+ del(src) {
1226
+ const cap = this.rules.inline.del.exec(src);
1227
+ if (cap) {
1228
+ return {
1229
+ type: 'del',
1230
+ raw: cap[0],
1231
+ text: cap[2],
1232
+ tokens: this.lexer.inlineTokens(cap[2]),
1233
+ };
1234
+ }
1235
+ }
1236
+ autolink(src) {
1237
+ const cap = this.rules.inline.autolink.exec(src);
1238
+ if (cap) {
1239
+ let text, href;
1240
+ if (cap[2] === '@') {
1241
+ text = cap[1];
1242
+ href = 'mailto:' + text;
1243
+ }
1244
+ else {
1245
+ text = cap[1];
1246
+ href = text;
1247
+ }
1248
+ return {
1249
+ type: 'link',
1250
+ raw: cap[0],
1251
+ text,
1252
+ href,
1253
+ tokens: [
1254
+ {
1255
+ type: 'text',
1256
+ raw: text,
1257
+ text,
1258
+ },
1259
+ ],
1260
+ };
1261
+ }
1262
+ }
1263
+ url(src) {
1264
+ let cap;
1265
+ if (cap = this.rules.inline.url.exec(src)) {
1266
+ let text, href;
1267
+ if (cap[2] === '@') {
1268
+ text = cap[0];
1269
+ href = 'mailto:' + text;
1270
+ }
1271
+ else {
1272
+ // do extended autolink path validation
1273
+ let prevCapZero;
1274
+ do {
1275
+ prevCapZero = cap[0];
1276
+ cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';
1277
+ } while (prevCapZero !== cap[0]);
1278
+ text = cap[0];
1279
+ if (cap[1] === 'www.') {
1280
+ href = 'http://' + cap[0];
1281
+ }
1282
+ else {
1283
+ href = cap[0];
1284
+ }
1285
+ }
1286
+ return {
1287
+ type: 'link',
1288
+ raw: cap[0],
1289
+ text,
1290
+ href,
1291
+ tokens: [
1292
+ {
1293
+ type: 'text',
1294
+ raw: text,
1295
+ text,
1296
+ },
1297
+ ],
1298
+ };
1299
+ }
1300
+ }
1301
+ inlineText(src) {
1302
+ const cap = this.rules.inline.text.exec(src);
1303
+ if (cap) {
1304
+ const escaped = this.lexer.state.inRawBlock;
1305
+ return {
1306
+ type: 'text',
1307
+ raw: cap[0],
1308
+ text: cap[0],
1309
+ escaped,
1310
+ };
1311
+ }
1312
+ }
1313
+ }
1314
+
1315
+ /**
1316
+ * Block Lexer
1317
+ */
1318
+ class _Lexer {
1319
+ tokens;
1320
+ options;
1321
+ state;
1322
+ tokenizer;
1323
+ inlineQueue;
1324
+ constructor(options) {
1325
+ // TokenList cannot be created in one go
1326
+ this.tokens = [];
1327
+ this.tokens.links = Object.create(null);
1328
+ this.options = options || exports.defaults;
1329
+ this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
1330
+ this.tokenizer = this.options.tokenizer;
1331
+ this.tokenizer.options = this.options;
1332
+ this.tokenizer.lexer = this;
1333
+ this.inlineQueue = [];
1334
+ this.state = {
1335
+ inLink: false,
1336
+ inRawBlock: false,
1337
+ top: true,
1338
+ };
1339
+ const rules = {
1340
+ other,
1341
+ block: block.normal,
1342
+ inline: inline.normal,
1343
+ };
1344
+ if (this.options.pedantic) {
1345
+ rules.block = block.pedantic;
1346
+ rules.inline = inline.pedantic;
1347
+ }
1348
+ else if (this.options.gfm) {
1349
+ rules.block = block.gfm;
1350
+ if (this.options.breaks) {
1351
+ rules.inline = inline.breaks;
1352
+ }
1353
+ else {
1354
+ rules.inline = inline.gfm;
1355
+ }
1356
+ }
1357
+ this.tokenizer.rules = rules;
1358
+ }
1359
+ /**
1360
+ * Expose Rules
1361
+ */
1362
+ static get rules() {
1363
+ return {
1364
+ block,
1365
+ inline,
1366
+ };
1367
+ }
1368
+ /**
1369
+ * Static Lex Method
1370
+ */
1371
+ static lex(src, options) {
1372
+ const lexer = new _Lexer(options);
1373
+ return lexer.lex(src);
1374
+ }
1375
+ /**
1376
+ * Static Lex Inline Method
1377
+ */
1378
+ static lexInline(src, options) {
1379
+ const lexer = new _Lexer(options);
1380
+ return lexer.inlineTokens(src);
1381
+ }
1382
+ /**
1383
+ * Preprocessing
1384
+ */
1385
+ lex(src) {
1386
+ src = src.replace(other.carriageReturn, '\n');
1387
+ this.blockTokens(src, this.tokens);
1388
+ for (let i = 0; i < this.inlineQueue.length; i++) {
1389
+ const next = this.inlineQueue[i];
1390
+ this.inlineTokens(next.src, next.tokens);
1391
+ }
1392
+ this.inlineQueue = [];
1393
+ return this.tokens;
1394
+ }
1395
+ blockTokens(src, tokens = [], lastParagraphClipped = false) {
1396
+ if (this.options.pedantic) {
1397
+ src = src.replace(other.tabCharGlobal, ' ').replace(other.spaceLine, '');
1398
+ }
1399
+ while (src) {
1400
+ let token;
1401
+ if (this.options.extensions?.block?.some((extTokenizer) => {
1402
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1403
+ src = src.substring(token.raw.length);
1404
+ tokens.push(token);
1405
+ return true;
1406
+ }
1407
+ return false;
1408
+ })) {
1409
+ continue;
1410
+ }
1411
+ // newline
1412
+ if (token = this.tokenizer.space(src)) {
1413
+ src = src.substring(token.raw.length);
1414
+ const lastToken = tokens.at(-1);
1415
+ if (token.raw.length === 1 && lastToken !== undefined) {
1416
+ // if there's a single \n as a spacer, it's terminating the last line,
1417
+ // so move it there so that we don't get unnecessary paragraph tags
1418
+ lastToken.raw += '\n';
1419
+ }
1420
+ else {
1421
+ tokens.push(token);
1422
+ }
1423
+ continue;
1424
+ }
1425
+ // code
1426
+ if (token = this.tokenizer.code(src)) {
1427
+ src = src.substring(token.raw.length);
1428
+ const lastToken = tokens.at(-1);
1429
+ // An indented code block cannot interrupt a paragraph.
1430
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
1431
+ lastToken.raw += '\n' + token.raw;
1432
+ lastToken.text += '\n' + token.text;
1433
+ this.inlineQueue.at(-1).src = lastToken.text;
1434
+ }
1435
+ else {
1436
+ tokens.push(token);
1437
+ }
1438
+ continue;
1439
+ }
1440
+ // fences
1441
+ if (token = this.tokenizer.fences(src)) {
1442
+ src = src.substring(token.raw.length);
1443
+ tokens.push(token);
1444
+ continue;
1445
+ }
1446
+ // heading
1447
+ if (token = this.tokenizer.heading(src)) {
1448
+ src = src.substring(token.raw.length);
1449
+ tokens.push(token);
1450
+ continue;
1451
+ }
1452
+ // hr
1453
+ if (token = this.tokenizer.hr(src)) {
1454
+ src = src.substring(token.raw.length);
1455
+ tokens.push(token);
1456
+ continue;
1457
+ }
1458
+ // blockquote
1459
+ if (token = this.tokenizer.blockquote(src)) {
1460
+ src = src.substring(token.raw.length);
1461
+ tokens.push(token);
1462
+ continue;
1463
+ }
1464
+ // list
1465
+ if (token = this.tokenizer.list(src)) {
1466
+ src = src.substring(token.raw.length);
1467
+ tokens.push(token);
1468
+ continue;
1469
+ }
1470
+ // html
1471
+ if (token = this.tokenizer.html(src)) {
1472
+ src = src.substring(token.raw.length);
1473
+ tokens.push(token);
1474
+ continue;
1475
+ }
1476
+ // def
1477
+ if (token = this.tokenizer.def(src)) {
1478
+ src = src.substring(token.raw.length);
1479
+ const lastToken = tokens.at(-1);
1480
+ if (lastToken?.type === 'paragraph' || lastToken?.type === 'text') {
1481
+ lastToken.raw += '\n' + token.raw;
1482
+ lastToken.text += '\n' + token.raw;
1483
+ this.inlineQueue.at(-1).src = lastToken.text;
1484
+ }
1485
+ else if (!this.tokens.links[token.tag]) {
1486
+ this.tokens.links[token.tag] = {
1487
+ href: token.href,
1488
+ title: token.title,
1489
+ };
1490
+ }
1491
+ continue;
1492
+ }
1493
+ // table (gfm)
1494
+ if (token = this.tokenizer.table(src)) {
1495
+ src = src.substring(token.raw.length);
1496
+ tokens.push(token);
1497
+ continue;
1498
+ }
1499
+ // lheading
1500
+ if (token = this.tokenizer.lheading(src)) {
1501
+ src = src.substring(token.raw.length);
1502
+ tokens.push(token);
1503
+ continue;
1504
+ }
1505
+ // top-level paragraph
1506
+ // prevent paragraph consuming extensions by clipping 'src' to extension start
1507
+ let cutSrc = src;
1508
+ if (this.options.extensions?.startBlock) {
1509
+ let startIndex = Infinity;
1510
+ const tempSrc = src.slice(1);
1511
+ let tempStart;
1512
+ this.options.extensions.startBlock.forEach((getStartIndex) => {
1513
+ tempStart = getStartIndex.call({ lexer: this }, tempSrc);
1514
+ if (typeof tempStart === 'number' && tempStart >= 0) {
1515
+ startIndex = Math.min(startIndex, tempStart);
1516
+ }
1517
+ });
1518
+ if (startIndex < Infinity && startIndex >= 0) {
1519
+ cutSrc = src.substring(0, startIndex + 1);
1520
+ }
1521
+ }
1522
+ if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
1523
+ const lastToken = tokens.at(-1);
1524
+ if (lastParagraphClipped && lastToken?.type === 'paragraph') {
1525
+ lastToken.raw += '\n' + token.raw;
1526
+ lastToken.text += '\n' + token.text;
1527
+ this.inlineQueue.pop();
1528
+ this.inlineQueue.at(-1).src = lastToken.text;
1529
+ }
1530
+ else {
1531
+ tokens.push(token);
1532
+ }
1533
+ lastParagraphClipped = cutSrc.length !== src.length;
1534
+ src = src.substring(token.raw.length);
1535
+ continue;
1536
+ }
1537
+ // text
1538
+ if (token = this.tokenizer.text(src)) {
1539
+ src = src.substring(token.raw.length);
1540
+ const lastToken = tokens.at(-1);
1541
+ if (lastToken?.type === 'text') {
1542
+ lastToken.raw += '\n' + token.raw;
1543
+ lastToken.text += '\n' + token.text;
1544
+ this.inlineQueue.pop();
1545
+ this.inlineQueue.at(-1).src = lastToken.text;
1546
+ }
1547
+ else {
1548
+ tokens.push(token);
1549
+ }
1550
+ continue;
1551
+ }
1552
+ if (src) {
1553
+ const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1554
+ if (this.options.silent) {
1555
+ console.error(errMsg);
1556
+ break;
1557
+ }
1558
+ else {
1559
+ throw new Error(errMsg);
1560
+ }
1561
+ }
1562
+ }
1563
+ this.state.top = true;
1564
+ return tokens;
1565
+ }
1566
+ inline(src, tokens = []) {
1567
+ this.inlineQueue.push({ src, tokens });
1568
+ return tokens;
1569
+ }
1570
+ /**
1571
+ * Lexing/Compiling
1572
+ */
1573
+ inlineTokens(src, tokens = []) {
1574
+ // String with links masked to avoid interference with em and strong
1575
+ let maskedSrc = src;
1576
+ let match = null;
1577
+ // Mask out reflinks
1578
+ if (this.tokens.links) {
1579
+ const links = Object.keys(this.tokens.links);
1580
+ if (links.length > 0) {
1581
+ while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
1582
+ if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
1583
+ maskedSrc = maskedSrc.slice(0, match.index)
1584
+ + '[' + 'a'.repeat(match[0].length - 2) + ']'
1585
+ + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
1586
+ }
1587
+ }
1588
+ }
1589
+ }
1590
+ // Mask out other blocks
1591
+ while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
1592
+ maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
1593
+ }
1594
+ // Mask out escaped characters
1595
+ while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
1596
+ maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
1597
+ }
1598
+ let keepPrevChar = false;
1599
+ let prevChar = '';
1600
+ while (src) {
1601
+ if (!keepPrevChar) {
1602
+ prevChar = '';
1603
+ }
1604
+ keepPrevChar = false;
1605
+ let token;
1606
+ // extensions
1607
+ if (this.options.extensions?.inline?.some((extTokenizer) => {
1608
+ if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1609
+ src = src.substring(token.raw.length);
1610
+ tokens.push(token);
1611
+ return true;
1612
+ }
1613
+ return false;
1614
+ })) {
1615
+ continue;
1616
+ }
1617
+ // escape
1618
+ if (token = this.tokenizer.escape(src)) {
1619
+ src = src.substring(token.raw.length);
1620
+ tokens.push(token);
1621
+ continue;
1622
+ }
1623
+ // tag
1624
+ if (token = this.tokenizer.tag(src)) {
1625
+ src = src.substring(token.raw.length);
1626
+ tokens.push(token);
1627
+ continue;
1628
+ }
1629
+ // link
1630
+ if (token = this.tokenizer.link(src)) {
1631
+ src = src.substring(token.raw.length);
1632
+ tokens.push(token);
1633
+ continue;
1634
+ }
1635
+ // reflink, nolink
1636
+ if (token = this.tokenizer.reflink(src, this.tokens.links)) {
1637
+ src = src.substring(token.raw.length);
1638
+ const lastToken = tokens.at(-1);
1639
+ if (token.type === 'text' && lastToken?.type === 'text') {
1640
+ lastToken.raw += token.raw;
1641
+ lastToken.text += token.text;
1642
+ }
1643
+ else {
1644
+ tokens.push(token);
1645
+ }
1646
+ continue;
1647
+ }
1648
+ // em & strong
1649
+ if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
1650
+ src = src.substring(token.raw.length);
1651
+ tokens.push(token);
1652
+ continue;
1653
+ }
1654
+ // code
1655
+ if (token = this.tokenizer.codespan(src)) {
1656
+ src = src.substring(token.raw.length);
1657
+ tokens.push(token);
1658
+ continue;
1659
+ }
1660
+ // br
1661
+ if (token = this.tokenizer.br(src)) {
1662
+ src = src.substring(token.raw.length);
1663
+ tokens.push(token);
1664
+ continue;
1665
+ }
1666
+ // del (gfm)
1667
+ if (token = this.tokenizer.del(src)) {
1668
+ src = src.substring(token.raw.length);
1669
+ tokens.push(token);
1670
+ continue;
1671
+ }
1672
+ // autolink
1673
+ if (token = this.tokenizer.autolink(src)) {
1674
+ src = src.substring(token.raw.length);
1675
+ tokens.push(token);
1676
+ continue;
1677
+ }
1678
+ // url (gfm)
1679
+ if (!this.state.inLink && (token = this.tokenizer.url(src))) {
1680
+ src = src.substring(token.raw.length);
1681
+ tokens.push(token);
1682
+ continue;
1683
+ }
1684
+ // text
1685
+ // prevent inlineText consuming extensions by clipping 'src' to extension start
1686
+ let cutSrc = src;
1687
+ if (this.options.extensions?.startInline) {
1688
+ let startIndex = Infinity;
1689
+ const tempSrc = src.slice(1);
1690
+ let tempStart;
1691
+ this.options.extensions.startInline.forEach((getStartIndex) => {
1692
+ tempStart = getStartIndex.call({ lexer: this }, tempSrc);
1693
+ if (typeof tempStart === 'number' && tempStart >= 0) {
1694
+ startIndex = Math.min(startIndex, tempStart);
1695
+ }
1696
+ });
1697
+ if (startIndex < Infinity && startIndex >= 0) {
1698
+ cutSrc = src.substring(0, startIndex + 1);
1699
+ }
1700
+ }
1701
+ if (token = this.tokenizer.inlineText(cutSrc)) {
1702
+ src = src.substring(token.raw.length);
1703
+ if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
1704
+ prevChar = token.raw.slice(-1);
1705
+ }
1706
+ keepPrevChar = true;
1707
+ const lastToken = tokens.at(-1);
1708
+ if (lastToken?.type === 'text') {
1709
+ lastToken.raw += token.raw;
1710
+ lastToken.text += token.text;
1711
+ }
1712
+ else {
1713
+ tokens.push(token);
1714
+ }
1715
+ continue;
1716
+ }
1717
+ if (src) {
1718
+ const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1719
+ if (this.options.silent) {
1720
+ console.error(errMsg);
1721
+ break;
1722
+ }
1723
+ else {
1724
+ throw new Error(errMsg);
1725
+ }
1726
+ }
1727
+ }
1728
+ return tokens;
1729
+ }
1730
+ }
1731
+
1732
+ /**
1733
+ * Renderer
1734
+ */
1735
+ class _Renderer {
1736
+ options;
1737
+ parser; // set by the parser
1738
+ constructor(options) {
1739
+ this.options = options || exports.defaults;
1740
+ }
1741
+ space(token) {
1742
+ return '';
1743
+ }
1744
+ code({ text, lang, escaped }) {
1745
+ const langString = (lang || '').match(other.notSpaceStart)?.[0];
1746
+ const code = text.replace(other.endingNewline, '') + '\n';
1747
+ if (!langString) {
1748
+ return '<pre><code>'
1749
+ + (escaped ? code : escape(code, true))
1750
+ + '</code></pre>\n';
1751
+ }
1752
+ return '<pre><code class="language-'
1753
+ + escape(langString)
1754
+ + '">'
1755
+ + (escaped ? code : escape(code, true))
1756
+ + '</code></pre>\n';
1757
+ }
1758
+ blockquote({ tokens }) {
1759
+ const body = this.parser.parse(tokens);
1760
+ return `<blockquote>\n${body}</blockquote>\n`;
1761
+ }
1762
+ html({ text }) {
1763
+ return text;
1764
+ }
1765
+ heading({ tokens, depth }) {
1766
+ return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\n`;
1767
+ }
1768
+ hr(token) {
1769
+ return '<hr>\n';
1770
+ }
1771
+ list(token) {
1772
+ const ordered = token.ordered;
1773
+ const start = token.start;
1774
+ let body = '';
1775
+ for (let j = 0; j < token.items.length; j++) {
1776
+ const item = token.items[j];
1777
+ body += this.listitem(item);
1778
+ }
1779
+ const type = ordered ? 'ol' : 'ul';
1780
+ const startAttr = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1781
+ return '<' + type + startAttr + '>\n' + body + '</' + type + '>\n';
1782
+ }
1783
+ listitem(item) {
1784
+ let itemBody = '';
1785
+ if (item.task) {
1786
+ const checkbox = this.checkbox({ checked: !!item.checked });
1787
+ if (item.loose) {
1788
+ if (item.tokens[0]?.type === 'paragraph') {
1789
+ item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
1790
+ if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
1791
+ item.tokens[0].tokens[0].text = checkbox + ' ' + escape(item.tokens[0].tokens[0].text);
1792
+ item.tokens[0].tokens[0].escaped = true;
1793
+ }
1794
+ }
1795
+ else {
1796
+ item.tokens.unshift({
1797
+ type: 'text',
1798
+ raw: checkbox + ' ',
1799
+ text: checkbox + ' ',
1800
+ escaped: true,
1801
+ });
1802
+ }
1803
+ }
1804
+ else {
1805
+ itemBody += checkbox + ' ';
1806
+ }
1807
+ }
1808
+ itemBody += this.parser.parse(item.tokens, !!item.loose);
1809
+ return `<li>${itemBody}</li>\n`;
1810
+ }
1811
+ checkbox({ checked }) {
1812
+ return '<input '
1813
+ + (checked ? 'checked="" ' : '')
1814
+ + 'disabled="" type="checkbox">';
1815
+ }
1816
+ paragraph({ tokens }) {
1817
+ return `<p>${this.parser.parseInline(tokens)}</p>\n`;
1818
+ }
1819
+ table(token) {
1820
+ let header = '';
1821
+ // header
1822
+ let cell = '';
1823
+ for (let j = 0; j < token.header.length; j++) {
1824
+ cell += this.tablecell(token.header[j]);
1825
+ }
1826
+ header += this.tablerow({ text: cell });
1827
+ let body = '';
1828
+ for (let j = 0; j < token.rows.length; j++) {
1829
+ const row = token.rows[j];
1830
+ cell = '';
1831
+ for (let k = 0; k < row.length; k++) {
1832
+ cell += this.tablecell(row[k]);
1833
+ }
1834
+ body += this.tablerow({ text: cell });
1835
+ }
1836
+ if (body)
1837
+ body = `<tbody>${body}</tbody>`;
1838
+ return '<table>\n'
1839
+ + '<thead>\n'
1840
+ + header
1841
+ + '</thead>\n'
1842
+ + body
1843
+ + '</table>\n';
1844
+ }
1845
+ tablerow({ text }) {
1846
+ return `<tr>\n${text}</tr>\n`;
1847
+ }
1848
+ tablecell(token) {
1849
+ const content = this.parser.parseInline(token.tokens);
1850
+ const type = token.header ? 'th' : 'td';
1851
+ const tag = token.align
1852
+ ? `<${type} align="${token.align}">`
1853
+ : `<${type}>`;
1854
+ return tag + content + `</${type}>\n`;
1855
+ }
1856
+ /**
1857
+ * span level renderer
1858
+ */
1859
+ strong({ tokens }) {
1860
+ return `<strong>${this.parser.parseInline(tokens)}</strong>`;
1861
+ }
1862
+ em({ tokens }) {
1863
+ return `<em>${this.parser.parseInline(tokens)}</em>`;
1864
+ }
1865
+ codespan({ text }) {
1866
+ return `<code>${escape(text, true)}</code>`;
1867
+ }
1868
+ br(token) {
1869
+ return '<br>';
1870
+ }
1871
+ del({ tokens }) {
1872
+ return `<del>${this.parser.parseInline(tokens)}</del>`;
1873
+ }
1874
+ link({ href, title, tokens }) {
1875
+ const text = this.parser.parseInline(tokens);
1876
+ const cleanHref = cleanUrl(href);
1877
+ if (cleanHref === null) {
1878
+ return text;
1879
+ }
1880
+ href = cleanHref;
1881
+ let out = '<a href="' + href + '"';
1882
+ if (title) {
1883
+ out += ' title="' + (escape(title)) + '"';
1884
+ }
1885
+ out += '>' + text + '</a>';
1886
+ return out;
1887
+ }
1888
+ image({ href, title, text }) {
1889
+ const cleanHref = cleanUrl(href);
1890
+ if (cleanHref === null) {
1891
+ return escape(text);
1892
+ }
1893
+ href = cleanHref;
1894
+ let out = `<img src="${href}" alt="${text}"`;
1895
+ if (title) {
1896
+ out += ` title="${escape(title)}"`;
1897
+ }
1898
+ out += '>';
1899
+ return out;
1900
+ }
1901
+ text(token) {
1902
+ return 'tokens' in token && token.tokens
1903
+ ? this.parser.parseInline(token.tokens)
1904
+ : ('escaped' in token && token.escaped ? token.text : escape(token.text));
1905
+ }
1906
+ }
1907
+
1908
+ /**
1909
+ * TextRenderer
1910
+ * returns only the textual part of the token
1911
+ */
1912
+ class _TextRenderer {
1913
+ // no need for block level renderers
1914
+ strong({ text }) {
1915
+ return text;
1916
+ }
1917
+ em({ text }) {
1918
+ return text;
1919
+ }
1920
+ codespan({ text }) {
1921
+ return text;
1922
+ }
1923
+ del({ text }) {
1924
+ return text;
1925
+ }
1926
+ html({ text }) {
1927
+ return text;
1928
+ }
1929
+ text({ text }) {
1930
+ return text;
1931
+ }
1932
+ link({ text }) {
1933
+ return '' + text;
1934
+ }
1935
+ image({ text }) {
1936
+ return '' + text;
1937
+ }
1938
+ br() {
1939
+ return '';
1940
+ }
1941
+ }
1942
+
1943
+ /**
1944
+ * Parsing & Compiling
1945
+ */
1946
+ class _Parser {
1947
+ options;
1948
+ renderer;
1949
+ textRenderer;
1950
+ constructor(options) {
1951
+ this.options = options || exports.defaults;
1952
+ this.options.renderer = this.options.renderer || new _Renderer();
1953
+ this.renderer = this.options.renderer;
1954
+ this.renderer.options = this.options;
1955
+ this.renderer.parser = this;
1956
+ this.textRenderer = new _TextRenderer();
1957
+ }
1958
+ /**
1959
+ * Static Parse Method
1960
+ */
1961
+ static parse(tokens, options) {
1962
+ const parser = new _Parser(options);
1963
+ return parser.parse(tokens);
1964
+ }
1965
+ /**
1966
+ * Static Parse Inline Method
1967
+ */
1968
+ static parseInline(tokens, options) {
1969
+ const parser = new _Parser(options);
1970
+ return parser.parseInline(tokens);
1971
+ }
1972
+ /**
1973
+ * Parse Loop
1974
+ */
1975
+ parse(tokens, top = true) {
1976
+ let out = '';
1977
+ for (let i = 0; i < tokens.length; i++) {
1978
+ const anyToken = tokens[i];
1979
+ // Run any renderer extensions
1980
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
1981
+ const genericToken = anyToken;
1982
+ const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
1983
+ if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
1984
+ out += ret || '';
1985
+ continue;
1986
+ }
1987
+ }
1988
+ const token = anyToken;
1989
+ switch (token.type) {
1990
+ case 'space': {
1991
+ out += this.renderer.space(token);
1992
+ continue;
1993
+ }
1994
+ case 'hr': {
1995
+ out += this.renderer.hr(token);
1996
+ continue;
1997
+ }
1998
+ case 'heading': {
1999
+ out += this.renderer.heading(token);
2000
+ continue;
2001
+ }
2002
+ case 'code': {
2003
+ out += this.renderer.code(token);
2004
+ continue;
2005
+ }
2006
+ case 'table': {
2007
+ out += this.renderer.table(token);
2008
+ continue;
2009
+ }
2010
+ case 'blockquote': {
2011
+ out += this.renderer.blockquote(token);
2012
+ continue;
2013
+ }
2014
+ case 'list': {
2015
+ out += this.renderer.list(token);
2016
+ continue;
2017
+ }
2018
+ case 'html': {
2019
+ out += this.renderer.html(token);
2020
+ continue;
2021
+ }
2022
+ case 'paragraph': {
2023
+ out += this.renderer.paragraph(token);
2024
+ continue;
2025
+ }
2026
+ case 'text': {
2027
+ let textToken = token;
2028
+ let body = this.renderer.text(textToken);
2029
+ while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
2030
+ textToken = tokens[++i];
2031
+ body += '\n' + this.renderer.text(textToken);
2032
+ }
2033
+ if (top) {
2034
+ out += this.renderer.paragraph({
2035
+ type: 'paragraph',
2036
+ raw: body,
2037
+ text: body,
2038
+ tokens: [{ type: 'text', raw: body, text: body, escaped: true }],
2039
+ });
2040
+ }
2041
+ else {
2042
+ out += body;
2043
+ }
2044
+ continue;
2045
+ }
2046
+ default: {
2047
+ const errMsg = 'Token with "' + token.type + '" type was not found.';
2048
+ if (this.options.silent) {
2049
+ console.error(errMsg);
2050
+ return '';
2051
+ }
2052
+ else {
2053
+ throw new Error(errMsg);
2054
+ }
2055
+ }
2056
+ }
2057
+ }
2058
+ return out;
2059
+ }
2060
+ /**
2061
+ * Parse Inline Tokens
2062
+ */
2063
+ parseInline(tokens, renderer = this.renderer) {
2064
+ let out = '';
2065
+ for (let i = 0; i < tokens.length; i++) {
2066
+ const anyToken = tokens[i];
2067
+ // Run any renderer extensions
2068
+ if (this.options.extensions?.renderers?.[anyToken.type]) {
2069
+ const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
2070
+ if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {
2071
+ out += ret || '';
2072
+ continue;
2073
+ }
2074
+ }
2075
+ const token = anyToken;
2076
+ switch (token.type) {
2077
+ case 'escape': {
2078
+ out += renderer.text(token);
2079
+ break;
2080
+ }
2081
+ case 'html': {
2082
+ out += renderer.html(token);
2083
+ break;
2084
+ }
2085
+ case 'link': {
2086
+ out += renderer.link(token);
2087
+ break;
2088
+ }
2089
+ case 'image': {
2090
+ out += renderer.image(token);
2091
+ break;
2092
+ }
2093
+ case 'strong': {
2094
+ out += renderer.strong(token);
2095
+ break;
2096
+ }
2097
+ case 'em': {
2098
+ out += renderer.em(token);
2099
+ break;
2100
+ }
2101
+ case 'codespan': {
2102
+ out += renderer.codespan(token);
2103
+ break;
2104
+ }
2105
+ case 'br': {
2106
+ out += renderer.br(token);
2107
+ break;
2108
+ }
2109
+ case 'del': {
2110
+ out += renderer.del(token);
2111
+ break;
2112
+ }
2113
+ case 'text': {
2114
+ out += renderer.text(token);
2115
+ break;
2116
+ }
2117
+ default: {
2118
+ const errMsg = 'Token with "' + token.type + '" type was not found.';
2119
+ if (this.options.silent) {
2120
+ console.error(errMsg);
2121
+ return '';
2122
+ }
2123
+ else {
2124
+ throw new Error(errMsg);
2125
+ }
2126
+ }
2127
+ }
2128
+ }
2129
+ return out;
2130
+ }
2131
+ }
2132
+
2133
+ class _Hooks {
2134
+ options;
2135
+ block;
2136
+ constructor(options) {
2137
+ this.options = options || exports.defaults;
2138
+ }
2139
+ static passThroughHooks = new Set([
2140
+ 'preprocess',
2141
+ 'postprocess',
2142
+ 'processAllTokens',
2143
+ ]);
2144
+ /**
2145
+ * Process markdown before marked
2146
+ */
2147
+ preprocess(markdown) {
2148
+ return markdown;
2149
+ }
2150
+ /**
2151
+ * Process HTML after marked is finished
2152
+ */
2153
+ postprocess(html) {
2154
+ return html;
2155
+ }
2156
+ /**
2157
+ * Process all tokens before walk tokens
2158
+ */
2159
+ processAllTokens(tokens) {
2160
+ return tokens;
2161
+ }
2162
+ /**
2163
+ * Provide function to tokenize markdown
2164
+ */
2165
+ provideLexer() {
2166
+ return this.block ? _Lexer.lex : _Lexer.lexInline;
2167
+ }
2168
+ /**
2169
+ * Provide function to parse tokens
2170
+ */
2171
+ provideParser() {
2172
+ return this.block ? _Parser.parse : _Parser.parseInline;
2173
+ }
2174
+ }
2175
+
2176
+ class Marked {
2177
+ defaults = _getDefaults();
2178
+ options = this.setOptions;
2179
+ parse = this.parseMarkdown(true);
2180
+ parseInline = this.parseMarkdown(false);
2181
+ Parser = _Parser;
2182
+ Renderer = _Renderer;
2183
+ TextRenderer = _TextRenderer;
2184
+ Lexer = _Lexer;
2185
+ Tokenizer = _Tokenizer;
2186
+ Hooks = _Hooks;
2187
+ constructor(...args) {
2188
+ this.use(...args);
2189
+ }
2190
+ /**
2191
+ * Run callback for every token
2192
+ */
2193
+ walkTokens(tokens, callback) {
2194
+ let values = [];
2195
+ for (const token of tokens) {
2196
+ values = values.concat(callback.call(this, token));
2197
+ switch (token.type) {
2198
+ case 'table': {
2199
+ const tableToken = token;
2200
+ for (const cell of tableToken.header) {
2201
+ values = values.concat(this.walkTokens(cell.tokens, callback));
2202
+ }
2203
+ for (const row of tableToken.rows) {
2204
+ for (const cell of row) {
2205
+ values = values.concat(this.walkTokens(cell.tokens, callback));
2206
+ }
2207
+ }
2208
+ break;
2209
+ }
2210
+ case 'list': {
2211
+ const listToken = token;
2212
+ values = values.concat(this.walkTokens(listToken.items, callback));
2213
+ break;
2214
+ }
2215
+ default: {
2216
+ const genericToken = token;
2217
+ if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
2218
+ this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
2219
+ const tokens = genericToken[childTokens].flat(Infinity);
2220
+ values = values.concat(this.walkTokens(tokens, callback));
2221
+ });
2222
+ }
2223
+ else if (genericToken.tokens) {
2224
+ values = values.concat(this.walkTokens(genericToken.tokens, callback));
2225
+ }
2226
+ }
2227
+ }
2228
+ }
2229
+ return values;
2230
+ }
2231
+ use(...args) {
2232
+ const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
2233
+ args.forEach((pack) => {
2234
+ // copy options to new object
2235
+ const opts = { ...pack };
2236
+ // set async to true if it was set to true before
2237
+ opts.async = this.defaults.async || opts.async || false;
2238
+ // ==-- Parse "addon" extensions --== //
2239
+ if (pack.extensions) {
2240
+ pack.extensions.forEach((ext) => {
2241
+ if (!ext.name) {
2242
+ throw new Error('extension name required');
2243
+ }
2244
+ if ('renderer' in ext) { // Renderer extensions
2245
+ const prevRenderer = extensions.renderers[ext.name];
2246
+ if (prevRenderer) {
2247
+ // Replace extension with func to run new extension but fall back if false
2248
+ extensions.renderers[ext.name] = function (...args) {
2249
+ let ret = ext.renderer.apply(this, args);
2250
+ if (ret === false) {
2251
+ ret = prevRenderer.apply(this, args);
2252
+ }
2253
+ return ret;
2254
+ };
2255
+ }
2256
+ else {
2257
+ extensions.renderers[ext.name] = ext.renderer;
2258
+ }
2259
+ }
2260
+ if ('tokenizer' in ext) { // Tokenizer Extensions
2261
+ if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
2262
+ throw new Error("extension level must be 'block' or 'inline'");
2263
+ }
2264
+ const extLevel = extensions[ext.level];
2265
+ if (extLevel) {
2266
+ extLevel.unshift(ext.tokenizer);
2267
+ }
2268
+ else {
2269
+ extensions[ext.level] = [ext.tokenizer];
2270
+ }
2271
+ if (ext.start) { // Function to check for start of token
2272
+ if (ext.level === 'block') {
2273
+ if (extensions.startBlock) {
2274
+ extensions.startBlock.push(ext.start);
2275
+ }
2276
+ else {
2277
+ extensions.startBlock = [ext.start];
2278
+ }
2279
+ }
2280
+ else if (ext.level === 'inline') {
2281
+ if (extensions.startInline) {
2282
+ extensions.startInline.push(ext.start);
2283
+ }
2284
+ else {
2285
+ extensions.startInline = [ext.start];
2286
+ }
2287
+ }
2288
+ }
2289
+ }
2290
+ if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens
2291
+ extensions.childTokens[ext.name] = ext.childTokens;
2292
+ }
2293
+ });
2294
+ opts.extensions = extensions;
2295
+ }
2296
+ // ==-- Parse "overwrite" extensions --== //
2297
+ if (pack.renderer) {
2298
+ const renderer = this.defaults.renderer || new _Renderer(this.defaults);
2299
+ for (const prop in pack.renderer) {
2300
+ if (!(prop in renderer)) {
2301
+ throw new Error(`renderer '${prop}' does not exist`);
2302
+ }
2303
+ if (['options', 'parser'].includes(prop)) {
2304
+ // ignore options property
2305
+ continue;
2306
+ }
2307
+ const rendererProp = prop;
2308
+ const rendererFunc = pack.renderer[rendererProp];
2309
+ const prevRenderer = renderer[rendererProp];
2310
+ // Replace renderer with func to run extension, but fall back if false
2311
+ renderer[rendererProp] = (...args) => {
2312
+ let ret = rendererFunc.apply(renderer, args);
2313
+ if (ret === false) {
2314
+ ret = prevRenderer.apply(renderer, args);
2315
+ }
2316
+ return ret || '';
2317
+ };
2318
+ }
2319
+ opts.renderer = renderer;
2320
+ }
2321
+ if (pack.tokenizer) {
2322
+ const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
2323
+ for (const prop in pack.tokenizer) {
2324
+ if (!(prop in tokenizer)) {
2325
+ throw new Error(`tokenizer '${prop}' does not exist`);
2326
+ }
2327
+ if (['options', 'rules', 'lexer'].includes(prop)) {
2328
+ // ignore options, rules, and lexer properties
2329
+ continue;
2330
+ }
2331
+ const tokenizerProp = prop;
2332
+ const tokenizerFunc = pack.tokenizer[tokenizerProp];
2333
+ const prevTokenizer = tokenizer[tokenizerProp];
2334
+ // Replace tokenizer with func to run extension, but fall back if false
2335
+ // @ts-expect-error cannot type tokenizer function dynamically
2336
+ tokenizer[tokenizerProp] = (...args) => {
2337
+ let ret = tokenizerFunc.apply(tokenizer, args);
2338
+ if (ret === false) {
2339
+ ret = prevTokenizer.apply(tokenizer, args);
2340
+ }
2341
+ return ret;
2342
+ };
2343
+ }
2344
+ opts.tokenizer = tokenizer;
2345
+ }
2346
+ // ==-- Parse Hooks extensions --== //
2347
+ if (pack.hooks) {
2348
+ const hooks = this.defaults.hooks || new _Hooks();
2349
+ for (const prop in pack.hooks) {
2350
+ if (!(prop in hooks)) {
2351
+ throw new Error(`hook '${prop}' does not exist`);
2352
+ }
2353
+ if (['options', 'block'].includes(prop)) {
2354
+ // ignore options and block properties
2355
+ continue;
2356
+ }
2357
+ const hooksProp = prop;
2358
+ const hooksFunc = pack.hooks[hooksProp];
2359
+ const prevHook = hooks[hooksProp];
2360
+ if (_Hooks.passThroughHooks.has(prop)) {
2361
+ // @ts-expect-error cannot type hook function dynamically
2362
+ hooks[hooksProp] = (arg) => {
2363
+ if (this.defaults.async) {
2364
+ return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {
2365
+ return prevHook.call(hooks, ret);
2366
+ });
2367
+ }
2368
+ const ret = hooksFunc.call(hooks, arg);
2369
+ return prevHook.call(hooks, ret);
2370
+ };
2371
+ }
2372
+ else {
2373
+ // @ts-expect-error cannot type hook function dynamically
2374
+ hooks[hooksProp] = (...args) => {
2375
+ let ret = hooksFunc.apply(hooks, args);
2376
+ if (ret === false) {
2377
+ ret = prevHook.apply(hooks, args);
2378
+ }
2379
+ return ret;
2380
+ };
2381
+ }
2382
+ }
2383
+ opts.hooks = hooks;
2384
+ }
2385
+ // ==-- Parse WalkTokens extensions --== //
2386
+ if (pack.walkTokens) {
2387
+ const walkTokens = this.defaults.walkTokens;
2388
+ const packWalktokens = pack.walkTokens;
2389
+ opts.walkTokens = function (token) {
2390
+ let values = [];
2391
+ values.push(packWalktokens.call(this, token));
2392
+ if (walkTokens) {
2393
+ values = values.concat(walkTokens.call(this, token));
2394
+ }
2395
+ return values;
2396
+ };
2397
+ }
2398
+ this.defaults = { ...this.defaults, ...opts };
2399
+ });
2400
+ return this;
2401
+ }
2402
+ setOptions(opt) {
2403
+ this.defaults = { ...this.defaults, ...opt };
2404
+ return this;
2405
+ }
2406
+ lexer(src, options) {
2407
+ return _Lexer.lex(src, options ?? this.defaults);
2408
+ }
2409
+ parser(tokens, options) {
2410
+ return _Parser.parse(tokens, options ?? this.defaults);
2411
+ }
2412
+ parseMarkdown(blockType) {
2413
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2414
+ const parse = (src, options) => {
2415
+ const origOpt = { ...options };
2416
+ const opt = { ...this.defaults, ...origOpt };
2417
+ const throwError = this.onError(!!opt.silent, !!opt.async);
2418
+ // throw error if an extension set async to true but parse was called with async: false
2419
+ if (this.defaults.async === true && origOpt.async === false) {
2420
+ return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));
2421
+ }
2422
+ // throw error in case of non string input
2423
+ if (typeof src === 'undefined' || src === null) {
2424
+ return throwError(new Error('marked(): input parameter is undefined or null'));
2425
+ }
2426
+ if (typeof src !== 'string') {
2427
+ return throwError(new Error('marked(): input parameter is of type '
2428
+ + Object.prototype.toString.call(src) + ', string expected'));
2429
+ }
2430
+ if (opt.hooks) {
2431
+ opt.hooks.options = opt;
2432
+ opt.hooks.block = blockType;
2433
+ }
2434
+ const lexer = opt.hooks ? opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);
2435
+ const parser = opt.hooks ? opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);
2436
+ if (opt.async) {
2437
+ return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
2438
+ .then(src => lexer(src, opt))
2439
+ .then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens)
2440
+ .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
2441
+ .then(tokens => parser(tokens, opt))
2442
+ .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
2443
+ .catch(throwError);
2444
+ }
2445
+ try {
2446
+ if (opt.hooks) {
2447
+ src = opt.hooks.preprocess(src);
2448
+ }
2449
+ let tokens = lexer(src, opt);
2450
+ if (opt.hooks) {
2451
+ tokens = opt.hooks.processAllTokens(tokens);
2452
+ }
2453
+ if (opt.walkTokens) {
2454
+ this.walkTokens(tokens, opt.walkTokens);
2455
+ }
2456
+ let html = parser(tokens, opt);
2457
+ if (opt.hooks) {
2458
+ html = opt.hooks.postprocess(html);
2459
+ }
2460
+ return html;
2461
+ }
2462
+ catch (e) {
2463
+ return throwError(e);
2464
+ }
2465
+ };
2466
+ return parse;
2467
+ }
2468
+ onError(silent, async) {
2469
+ return (e) => {
2470
+ e.message += '\nPlease report this to https://github.com/markedjs/marked.';
2471
+ if (silent) {
2472
+ const msg = '<p>An error occurred:</p><pre>'
2473
+ + escape(e.message + '', true)
2474
+ + '</pre>';
2475
+ if (async) {
2476
+ return Promise.resolve(msg);
2477
+ }
2478
+ return msg;
2479
+ }
2480
+ if (async) {
2481
+ return Promise.reject(e);
2482
+ }
2483
+ throw e;
2484
+ };
2485
+ }
2486
+ }
2487
+
2488
+ const markedInstance = new Marked();
2489
+ function marked(src, opt) {
2490
+ return markedInstance.parse(src, opt);
2491
+ }
2492
+ /**
2493
+ * Sets the default options.
2494
+ *
2495
+ * @param options Hash of options
2496
+ */
2497
+ marked.options =
2498
+ marked.setOptions = function (options) {
2499
+ markedInstance.setOptions(options);
2500
+ marked.defaults = markedInstance.defaults;
2501
+ changeDefaults(marked.defaults);
2502
+ return marked;
2503
+ };
2504
+ /**
2505
+ * Gets the original marked default options.
2506
+ */
2507
+ marked.getDefaults = _getDefaults;
2508
+ marked.defaults = exports.defaults;
2509
+ /**
2510
+ * Use Extension
2511
+ */
2512
+ marked.use = function (...args) {
2513
+ markedInstance.use(...args);
2514
+ marked.defaults = markedInstance.defaults;
2515
+ changeDefaults(marked.defaults);
2516
+ return marked;
2517
+ };
2518
+ /**
2519
+ * Run callback for every token
2520
+ */
2521
+ marked.walkTokens = function (tokens, callback) {
2522
+ return markedInstance.walkTokens(tokens, callback);
2523
+ };
2524
+ /**
2525
+ * Compiles markdown to HTML without enclosing `p` tag.
2526
+ *
2527
+ * @param src String of markdown source to be compiled
2528
+ * @param options Hash of options
2529
+ * @return String of compiled HTML
2530
+ */
2531
+ marked.parseInline = markedInstance.parseInline;
2532
+ /**
2533
+ * Expose
2534
+ */
2535
+ marked.Parser = _Parser;
2536
+ marked.parser = _Parser.parse;
2537
+ marked.Renderer = _Renderer;
2538
+ marked.TextRenderer = _TextRenderer;
2539
+ marked.Lexer = _Lexer;
2540
+ marked.lexer = _Lexer.lex;
2541
+ marked.Tokenizer = _Tokenizer;
2542
+ marked.Hooks = _Hooks;
2543
+ marked.parse = marked;
2544
+ const options = marked.options;
2545
+ const setOptions = marked.setOptions;
2546
+ const use = marked.use;
2547
+ const walkTokens = marked.walkTokens;
2548
+ const parseInline = marked.parseInline;
2549
+ const parse = marked;
2550
+ const parser = _Parser.parse;
2551
+ const lexer = _Lexer.lex;
2552
+
2553
+ exports.Hooks = _Hooks;
2554
+ exports.Lexer = _Lexer;
2555
+ exports.Marked = Marked;
2556
+ exports.Parser = _Parser;
2557
+ exports.Renderer = _Renderer;
2558
+ exports.TextRenderer = _TextRenderer;
2559
+ exports.Tokenizer = _Tokenizer;
2560
+ exports.getDefaults = _getDefaults;
2561
+ exports.lexer = lexer;
2562
+ exports.marked = marked;
2563
+ exports.options = options;
2564
+ exports.parse = parse;
2565
+ exports.parseInline = parseInline;
2566
+ exports.parser = parser;
2567
+ exports.setOptions = setOptions;
2568
+ exports.use = use;
2569
+ exports.walkTokens = walkTokens;
2570
+ //# sourceMappingURL=marked.cjs.map