marked 5.1.2 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,7 @@
1
+ import type { MarkedOptions } from './MarkedOptions.ts';
2
+ import type { ResultCallback } from './marked.ts';
3
+ import type { Rule } from './rules.ts';
4
+
1
5
  /**
2
6
  * Helpers
3
7
  */
@@ -12,8 +16,9 @@ const escapeReplacements = {
12
16
  '"': '"',
13
17
  "'": '''
14
18
  };
15
- const getEscapeReplacement = (ch) => escapeReplacements[ch];
16
- export function escape(html, encode) {
19
+ const getEscapeReplacement = (ch: string) => escapeReplacements[ch];
20
+
21
+ export function escape(html: string, encode?: boolean) {
17
22
  if (encode) {
18
23
  if (escapeTest.test(html)) {
19
24
  return html.replace(escapeReplace, getEscapeReplacement);
@@ -29,10 +34,7 @@ export function escape(html, encode) {
29
34
 
30
35
  const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
31
36
 
32
- /**
33
- * @param {string} html
34
- */
35
- export function unescape(html) {
37
+ export function unescape(html: string) {
36
38
  // explicitly match decimal, hex, and named HTML entities
37
39
  return html.replace(unescapeTest, (_, n) => {
38
40
  n = n.toLowerCase();
@@ -48,18 +50,14 @@ export function unescape(html) {
48
50
 
49
51
  const caret = /(^|[^\[])\^/g;
50
52
 
51
- /**
52
- * @param {string | RegExp} regex
53
- * @param {string} opt
54
- */
55
- export function edit(regex, opt) {
53
+ export function edit(regex: Rule, opt?: string) {
56
54
  regex = typeof regex === 'string' ? regex : regex.source;
57
55
  opt = opt || '';
58
56
  const obj = {
59
- replace: (name, val) => {
60
- val = val.source || val;
57
+ replace: (name: string | RegExp, val: string | RegExp) => {
58
+ val = typeof val === 'object' && 'source' in val ? val.source : val;
61
59
  val = val.replace(caret, '$1');
62
- regex = regex.replace(name, val);
60
+ regex = (regex as string).replace(name, val);
63
61
  return obj;
64
62
  },
65
63
  getRegex: () => {
@@ -72,12 +70,7 @@ export function edit(regex, opt) {
72
70
  const nonWordAndColonTest = /[^\w:]/g;
73
71
  const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
74
72
 
75
- /**
76
- * @param {boolean} sanitize
77
- * @param {string} base
78
- * @param {string} href
79
- */
80
- export function cleanUrl(sanitize, base, href) {
73
+ export function cleanUrl(sanitize: boolean | undefined, base: string | undefined | null, href: string) {
81
74
  if (sanitize) {
82
75
  let prot;
83
76
  try {
@@ -102,16 +95,12 @@ export function cleanUrl(sanitize, base, href) {
102
95
  return href;
103
96
  }
104
97
 
105
- const baseUrls = {};
98
+ const baseUrls: Record<string, string> = {};
106
99
  const justDomain = /^[^:]+:\/*[^/]*$/;
107
100
  const protocol = /^([^:]+:)[\s\S]*$/;
108
101
  const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
109
102
 
110
- /**
111
- * @param {string} base
112
- * @param {string} href
113
- */
114
- export function resolveUrl(base, href) {
103
+ export function resolveUrl(base: string, href: string) {
115
104
  if (!baseUrls[' ' + base]) {
116
105
  // we can ignore everything in base after the last slash of its path component,
117
106
  // but we might need to add _that_
@@ -140,9 +129,9 @@ export function resolveUrl(base, href) {
140
129
  }
141
130
  }
142
131
 
143
- export const noopTest = { exec: function noopTest() {} };
132
+ export const noopTest = { exec: () => null };
144
133
 
145
- export function splitCells(tableRow, count) {
134
+ export function splitCells(tableRow: string, count: number) {
146
135
  // ensure that every cell-delimiting pipe has a space
147
136
  // before it to distinguish it from an escaped pipe
148
137
  const row = tableRow.replace(/\|/g, (match, offset, str) => {
@@ -162,8 +151,12 @@ export function splitCells(tableRow, count) {
162
151
  let i = 0;
163
152
 
164
153
  // First/last cell in a row cannot be empty if it has no leading/trailing pipe
165
- if (!cells[0].trim()) { cells.shift(); }
166
- if (cells.length > 0 && !cells[cells.length - 1].trim()) { cells.pop(); }
154
+ if (!cells[0].trim()) {
155
+ cells.shift();
156
+ }
157
+ if (cells.length > 0 && !cells[cells.length - 1].trim()) {
158
+ cells.pop();
159
+ }
167
160
 
168
161
  if (cells.length > count) {
169
162
  cells.splice(count);
@@ -182,11 +175,11 @@ export function splitCells(tableRow, count) {
182
175
  * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
183
176
  * /c*$/ is vulnerable to REDOS.
184
177
  *
185
- * @param {string} str
186
- * @param {string} c
187
- * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
178
+ * @param str
179
+ * @param c
180
+ * @param invert Remove suffix of non-c chars instead. Default falsey.
188
181
  */
189
- export function rtrim(str, c, invert) {
182
+ export function rtrim(str: string, c: string, invert?: boolean) {
190
183
  const l = str.length;
191
184
  if (l === 0) {
192
185
  return '';
@@ -210,7 +203,7 @@ export function rtrim(str, c, invert) {
210
203
  return str.slice(0, l - suffLen);
211
204
  }
212
205
 
213
- export function findClosingBracket(str, b) {
206
+ export function findClosingBracket(str: string, b: string) {
214
207
  if (str.indexOf(b[1]) === -1) {
215
208
  return -1;
216
209
  }
@@ -232,7 +225,7 @@ export function findClosingBracket(str, b) {
232
225
  return -1;
233
226
  }
234
227
 
235
- export function checkDeprecations(opt, callback) {
228
+ export function checkDeprecations(opt: MarkedOptions, callback?: ResultCallback) {
236
229
  if (!opt || opt.silent) {
237
230
  return;
238
231
  }
package/src/marked.ts ADDED
@@ -0,0 +1,144 @@
1
+ import { _Lexer } from './Lexer.ts';
2
+ import { _Parser } from './Parser.ts';
3
+ import { _Tokenizer } from './Tokenizer.ts';
4
+ import { _Renderer } from './Renderer.ts';
5
+ import { _TextRenderer } from './TextRenderer.ts';
6
+ import { _Slugger } from './Slugger.ts';
7
+ import { _Hooks } from './Hooks.ts';
8
+ import { Marked } from './Instance.ts';
9
+ import {
10
+ _getDefaults,
11
+ changeDefaults,
12
+ _defaults
13
+ } from './defaults.ts';
14
+ import type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';
15
+ import type { Token, TokensList } from './Tokens.ts';
16
+
17
+ export type ResultCallback = (error: Error | null, parseResult?: string) => undefined | void;
18
+
19
+ const markedInstance = new Marked();
20
+
21
+ /**
22
+ * Compiles markdown to HTML asynchronously.
23
+ *
24
+ * @param src String of markdown source to be compiled
25
+ * @param options Hash of options, having async: true
26
+ * @return Promise of string of compiled HTML
27
+ */
28
+ export function marked(src: string, options: MarkedOptions & { async: true }): Promise<string>;
29
+
30
+ /**
31
+ * Compiles markdown to HTML synchronously.
32
+ *
33
+ * @param src String of markdown source to be compiled
34
+ * @param options Optional hash of options
35
+ * @return String of compiled HTML
36
+ */
37
+ export function marked(src: string, options?: MarkedOptions): string;
38
+
39
+ /**
40
+ * Compiles markdown to HTML asynchronously with a callback.
41
+ *
42
+ * @param src String of markdown source to be compiled
43
+ * @param callback Function called when the markdownString has been fully parsed when using async highlighting
44
+ */
45
+ export function marked(src: string, callback: ResultCallback): void;
46
+
47
+ /**
48
+ * Compiles markdown to HTML asynchronously with a callback.
49
+ *
50
+ * @param src String of markdown source to be compiled
51
+ * @param options Hash of options
52
+ * @param callback Function called when the markdownString has been fully parsed when using async highlighting
53
+ */
54
+ export function marked(
55
+ src: string,
56
+ options: MarkedOptions,
57
+ callback: ResultCallback,
58
+ ): void;
59
+ export function marked(src: string, opt?: MarkedOptions | ResultCallback, callback?: ResultCallback): string | Promise<string | undefined> | undefined {
60
+ return markedInstance.parse(src, opt, callback);
61
+ }
62
+
63
+ /**
64
+ * Sets the default options.
65
+ *
66
+ * @param options Hash of options
67
+ */
68
+ marked.options =
69
+ marked.setOptions = function(options: MarkedOptions) {
70
+ markedInstance.setOptions(options);
71
+ marked.defaults = markedInstance.defaults;
72
+ changeDefaults(marked.defaults);
73
+ return marked;
74
+ };
75
+
76
+ /**
77
+ * Gets the original marked default options.
78
+ */
79
+ marked.getDefaults = _getDefaults;
80
+
81
+ marked.defaults = _defaults;
82
+
83
+ /**
84
+ * Use Extension
85
+ */
86
+
87
+ marked.use = function(...args: MarkedExtension[]) {
88
+ markedInstance.use(...args);
89
+ marked.defaults = markedInstance.defaults;
90
+ changeDefaults(marked.defaults);
91
+ return marked;
92
+ };
93
+
94
+ /**
95
+ * Run callback for every token
96
+ */
97
+
98
+ marked.walkTokens = function <T = void>(tokens: Token[] | TokensList, callback: (token: Token) => T | T[]) {
99
+ return markedInstance.walkTokens(tokens, callback);
100
+ };
101
+
102
+ /**
103
+ * Compiles markdown to HTML without enclosing `p` tag.
104
+ *
105
+ * @param src String of markdown source to be compiled
106
+ * @param options Hash of options
107
+ * @return String of compiled HTML
108
+ */
109
+ marked.parseInline = markedInstance.parseInline;
110
+
111
+ /**
112
+ * Expose
113
+ */
114
+ marked.Parser = _Parser;
115
+ marked.parser = _Parser.parse;
116
+ marked.Renderer = _Renderer;
117
+ marked.TextRenderer = _TextRenderer;
118
+ marked.Lexer = _Lexer;
119
+ marked.lexer = _Lexer.lex;
120
+ marked.Tokenizer = _Tokenizer;
121
+ marked.Slugger = _Slugger;
122
+ marked.Hooks = _Hooks;
123
+ marked.parse = marked;
124
+
125
+ export const options = marked.options;
126
+ export const setOptions = marked.setOptions;
127
+ export const use = marked.use;
128
+ export const walkTokens = marked.walkTokens;
129
+ export const parseInline = marked.parseInline;
130
+ export const parse = marked;
131
+ export const parser = _Parser.parse;
132
+ export const lexer = _Lexer.lex;
133
+ export { _defaults as defaults, _getDefaults as getDefaults } from './defaults.ts';
134
+ export { _Lexer as Lexer } from './Lexer.ts';
135
+ export { _Parser as Parser } from './Parser.ts';
136
+ export { _Tokenizer as Tokenizer } from './Tokenizer.ts';
137
+ export { _Renderer as Renderer } from './Renderer.ts';
138
+ export { _TextRenderer as TextRenderer } from './TextRenderer.ts';
139
+ export { _Slugger as Slugger } from './Slugger.ts';
140
+ export { _Hooks as Hooks } from './Hooks.ts';
141
+ export { Marked } from './Instance.ts';
142
+ export type * from './MarkedOptions.ts';
143
+ export type * from './rules.ts';
144
+ export type * from './Tokens.ts';
@@ -1,12 +1,73 @@
1
1
  import {
2
2
  noopTest,
3
3
  edit
4
- } from './helpers.js';
4
+ } from './helpers.ts';
5
+
6
+ export type Rule = RegExp | string;
7
+
8
+ export interface Rules {
9
+ [ruleName: string]: Pick<RegExp, 'exec'> | Rule | Rules;
10
+ }
11
+
12
+ type BlockRuleNames =
13
+ | 'newline'
14
+ | 'code'
15
+ | 'fences'
16
+ | 'hr'
17
+ | 'heading'
18
+ | 'blockquote'
19
+ | 'list'
20
+ | 'html'
21
+ | 'def'
22
+ | 'lheading'
23
+ | '_paragraph'
24
+ | 'text'
25
+ | '_label'
26
+ | '_title'
27
+ | 'bullet'
28
+ | 'listItemStart'
29
+ | '_tag'
30
+ | '_comment'
31
+ | 'paragraph'
32
+ | 'uote' ;
33
+
34
+ type BlockSubRuleNames = 'normal' | 'gfm' | 'pedantic';
35
+
36
+ type InlineRuleNames =
37
+ | 'escape'
38
+ | 'autolink'
39
+ | 'tag'
40
+ | 'link'
41
+ | 'reflink'
42
+ | 'nolink'
43
+ | 'reflinkSearch'
44
+ | 'code'
45
+ | 'br'
46
+ | 'text'
47
+ | '_punctuation'
48
+ | 'punctuation'
49
+ | 'blockSkip'
50
+ | 'escapedEmSt'
51
+ | '_comment'
52
+ | '_escapes'
53
+ | '_scheme'
54
+ | '_email'
55
+ | '_attribute'
56
+ | '_label'
57
+ | '_href'
58
+ | '_title'
59
+ | 'strong'
60
+ | '_extended_email'
61
+ | '_backpedal';
62
+
63
+ type InlineSubRuleNames = 'gfm' | 'emStrong' | 'normal' | 'pedantic'| 'breaks';
5
64
 
6
65
  /**
7
66
  * Block-Level Grammar
8
67
  */
9
- export const block = {
68
+ // Not all rules are defined in the object literal
69
+ // @ts-expect-error
70
+ export const block: Record<BlockRuleNames, Rule> & Record<BlockSubRuleNames, Rules> & Rules = {
10
71
  newline: /^(?: *(?:\n|$))+/,
11
72
  code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
12
73
  fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
@@ -101,7 +162,7 @@ block.gfm = {
101
162
  + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
102
163
  };
103
164
 
104
- block.gfm.table = edit(block.gfm.table)
165
+ block.gfm.table = edit(block.gfm.table as Rule)
105
166
  .replace('hr', block.hr)
106
167
  .replace('heading', ' {0,3}#{1,6} ')
107
168
  .replace('blockquote', ' {0,3}>')
@@ -116,7 +177,7 @@ block.gfm.paragraph = edit(block._paragraph)
116
177
  .replace('hr', block.hr)
117
178
  .replace('heading', ' {0,3}#{1,6} ')
118
179
  .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
119
- .replace('table', block.gfm.table) // interrupt paragraphs with table
180
+ .replace('table', block.gfm.table as RegExp) // interrupt paragraphs with table
120
181
  .replace('blockquote', ' {0,3}>')
121
182
  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
122
183
  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
@@ -143,7 +204,7 @@ block.pedantic = {
143
204
  heading: /^(#{1,6})(.*)(?:\n+|$)/,
144
205
  fences: noopTest, // fences not supported
145
206
  lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
146
- paragraph: edit(block.normal._paragraph)
207
+ paragraph: edit(block.normal._paragraph as Rule)
147
208
  .replace('hr', block.hr)
148
209
  .replace('heading', ' *#{1,6} *[^\n]')
149
210
  .replace('lheading', block.lheading)
@@ -157,7 +218,9 @@ block.pedantic = {
157
218
  /**
158
219
  * Inline-Level Grammar
159
220
  */
160
- export const inline = {
221
+ // Not all rules are defined in the object literal
222
+ // @ts-expect-error
223
+ export const inline: Record<InlineRuleNames, Rule> & Record<InlineSubRuleNames, Rules> & Rules = {
161
224
  escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
162
225
  autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
163
226
  url: noopTest,
@@ -196,19 +259,19 @@ inline._escapes = /\\([punct])/g;
196
259
 
197
260
  inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
198
261
 
199
- inline.emStrong.lDelim = edit(inline.emStrong.lDelim, 'u')
262
+ inline.emStrong.lDelim = edit(inline.emStrong.lDelim as Rule, 'u')
200
263
  .replace(/punct/g, inline._punctuation)
201
264
  .getRegex();
202
265
 
203
- inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'gu')
266
+ inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst as Rule, 'gu')
204
267
  .replace(/punct/g, inline._punctuation)
205
268
  .getRegex();
206
269
 
207
- inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'gu')
270
+ inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd as Rule, 'gu')
208
271
  .replace(/punct/g, inline._punctuation)
209
272
  .getRegex();
210
273
 
211
- inline.anyPunctuation = edit(inline.anyPunctuation, 'gu')
274
+ inline.anyPunctuation = edit(inline.anyPunctuation as Rule, 'gu')
212
275
  .replace(/punct/g, inline._punctuation)
213
276
  .getRegex();
214
277
 
@@ -300,8 +363,8 @@ inline.gfm = {
300
363
  text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
301
364
  };
302
365
 
303
- inline.gfm.url = edit(inline.gfm.url, 'i')
304
- .replace('email', inline.gfm._extended_email)
366
+ inline.gfm.url = edit(inline.gfm.url as Rule, 'i')
367
+ .replace('email', inline.gfm._extended_email as RegExp)
305
368
  .getRegex();
306
369
  /**
307
370
  * GFM + Line Breaks Inline Grammar
@@ -310,7 +373,7 @@ inline.gfm.url = edit(inline.gfm.url, 'i')
310
373
  inline.breaks = {
311
374
  ...inline.gfm,
312
375
  br: edit(inline.br).replace('{2,}', '*').getRegex(),
313
- text: edit(inline.gfm.text)
376
+ text: edit(inline.gfm.text as Rule)
314
377
  .replace('\\b_', '\\b_| {2,}\\n')
315
378
  .replace(/\{2,\}/g, '*')
316
379
  .getRegex()
package/src/Hooks.js DELETED
@@ -1,26 +0,0 @@
1
- import { defaults } from './defaults.js';
2
-
3
- export class Hooks {
4
- constructor(options) {
5
- this.options = options || defaults;
6
- }
7
-
8
- static passThroughHooks = new Set([
9
- 'preprocess',
10
- 'postprocess'
11
- ]);
12
-
13
- /**
14
- * Process markdown before marked
15
- */
16
- preprocess(markdown) {
17
- return markdown;
18
- }
19
-
20
- /**
21
- * Process HTML after marked is finished
22
- */
23
- postprocess(html) {
24
- return html;
25
- }
26
- }
package/src/marked.js DELETED
@@ -1,91 +0,0 @@
1
- import { Lexer } from './Lexer.js';
2
- import { Parser } from './Parser.js';
3
- import { Tokenizer } from './Tokenizer.js';
4
- import { Renderer } from './Renderer.js';
5
- import { TextRenderer } from './TextRenderer.js';
6
- import { Slugger } from './Slugger.js';
7
- import { Hooks } from './Hooks.js';
8
- import { Marked } from './Instance.js';
9
- import { changeDefaults, getDefaults, defaults } from './defaults.js';
10
-
11
- const markedInstance = new Marked(defaults);
12
-
13
- /**
14
- * Marked
15
- */
16
- export function marked(src, opt, callback) {
17
- return markedInstance.parse(src, opt, callback);
18
- }
19
-
20
- /**
21
- * Options
22
- */
23
-
24
- marked.options =
25
- marked.setOptions = function(opt) {
26
- markedInstance.setOptions(opt);
27
- marked.defaults = markedInstance.defaults;
28
- changeDefaults(marked.defaults);
29
- return marked;
30
- };
31
-
32
- marked.getDefaults = getDefaults;
33
-
34
- marked.defaults = defaults;
35
-
36
- /**
37
- * Use Extension
38
- */
39
-
40
- marked.use = function(...args) {
41
- markedInstance.use(...args);
42
- marked.defaults = markedInstance.defaults;
43
- changeDefaults(marked.defaults);
44
- return marked;
45
- };
46
-
47
- /**
48
- * Run callback for every token
49
- */
50
-
51
- marked.walkTokens = function(tokens, callback) {
52
- return markedInstance.walkTokens(tokens, callback);
53
- };
54
-
55
- /**
56
- * Parse Inline
57
- * @param {string} src
58
- */
59
- marked.parseInline = markedInstance.parseInline;
60
-
61
- /**
62
- * Expose
63
- */
64
- marked.Parser = Parser;
65
- marked.parser = Parser.parse;
66
- marked.Renderer = Renderer;
67
- marked.TextRenderer = TextRenderer;
68
- marked.Lexer = Lexer;
69
- marked.lexer = Lexer.lex;
70
- marked.Tokenizer = Tokenizer;
71
- marked.Slugger = Slugger;
72
- marked.Hooks = Hooks;
73
- marked.parse = marked;
74
-
75
- export const options = marked.options;
76
- export const setOptions = marked.setOptions;
77
- export const use = marked.use;
78
- export const walkTokens = marked.walkTokens;
79
- export const parseInline = marked.parseInline;
80
- export const parse = marked;
81
- export const parser = Parser.parse;
82
- export const lexer = Lexer.lex;
83
- export { defaults, getDefaults } from './defaults.js';
84
- export { Lexer } from './Lexer.js';
85
- export { Parser } from './Parser.js';
86
- export { Tokenizer } from './Tokenizer.js';
87
- export { Renderer } from './Renderer.js';
88
- export { TextRenderer } from './TextRenderer.js';
89
- export { Slugger } from './Slugger.js';
90
- export { Hooks } from './Hooks.js';
91
- export { Marked } from './Instance.js';