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,19 +1,22 @@
1
- import { defaults } from './defaults.js';
1
+ import { _defaults } from './defaults.ts';
2
2
  import {
3
3
  rtrim,
4
4
  splitCells,
5
5
  escape,
6
6
  findClosingBracket
7
- } from './helpers.js';
7
+ } from './helpers.ts';
8
+ import { _Lexer } from './Lexer.ts';
9
+ import type { Links, Tokens } from './Tokens.ts';
10
+ import type { MarkedOptions } from './MarkedOptions.ts';
8
11
 
9
- function outputLink(cap, link, raw, lexer) {
12
+ function outputLink(cap: string[], link: Pick<Tokens.Link, 'href' | 'title'>, raw: string, lexer: _Lexer): Tokens.Link | Tokens.Image {
10
13
  const href = link.href;
11
14
  const title = link.title ? escape(link.title) : null;
12
15
  const text = cap[1].replace(/\\([\[\]])/g, '$1');
13
16
 
14
17
  if (cap[0].charAt(0) !== '!') {
15
18
  lexer.state.inLink = true;
16
- const token = {
19
+ const token: Tokens.Link = {
17
20
  type: 'link',
18
21
  raw,
19
22
  href,
@@ -33,7 +36,7 @@ function outputLink(cap, link, raw, lexer) {
33
36
  };
34
37
  }
35
38
 
36
- function indentCodeCompensation(raw, text) {
39
+ function indentCodeCompensation(raw: string, text: string) {
37
40
  const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
38
41
 
39
42
  if (matchIndentToCode === null) {
@@ -64,12 +67,16 @@ function indentCodeCompensation(raw, text) {
64
67
  /**
65
68
  * Tokenizer
66
69
  */
67
- export class Tokenizer {
68
- constructor(options) {
69
- this.options = options || defaults;
70
+ export class _Tokenizer {
71
+ options: MarkedOptions;
72
+ rules: any;
73
+ lexer!: _Lexer;
74
+
75
+ constructor(options?: MarkedOptions) {
76
+ this.options = options || _defaults;
70
77
  }
71
78
 
72
- space(src) {
79
+ space(src: string): Tokens.Space | undefined {
73
80
  const cap = this.rules.block.newline.exec(src);
74
81
  if (cap && cap[0].length > 0) {
75
82
  return {
@@ -79,7 +86,7 @@ export class Tokenizer {
79
86
  }
80
87
  }
81
88
 
82
- code(src) {
89
+ code(src: string): Tokens.Code | undefined {
83
90
  const cap = this.rules.block.code.exec(src);
84
91
  if (cap) {
85
92
  const text = cap[0].replace(/^ {1,4}/gm, '');
@@ -94,7 +101,7 @@ export class Tokenizer {
94
101
  }
95
102
  }
96
103
 
97
- fences(src) {
104
+ fences(src: string): Tokens.Code | undefined {
98
105
  const cap = this.rules.block.fences.exec(src);
99
106
  if (cap) {
100
107
  const raw = cap[0];
@@ -109,7 +116,7 @@ export class Tokenizer {
109
116
  }
110
117
  }
111
118
 
112
- heading(src) {
119
+ heading(src: string): Tokens.Heading | undefined {
113
120
  const cap = this.rules.block.heading.exec(src);
114
121
  if (cap) {
115
122
  let text = cap[2].trim();
@@ -135,7 +142,7 @@ export class Tokenizer {
135
142
  }
136
143
  }
137
144
 
138
- hr(src) {
145
+ hr(src: string): Tokens.Hr | undefined {
139
146
  const cap = this.rules.block.hr.exec(src);
140
147
  if (cap) {
141
148
  return {
@@ -145,7 +152,7 @@ export class Tokenizer {
145
152
  }
146
153
  }
147
154
 
148
- blockquote(src) {
155
+ blockquote(src: string): Tokens.Blockquote | undefined {
149
156
  const cap = this.rules.block.blockquote.exec(src);
150
157
  if (cap) {
151
158
  const text = cap[0].replace(/^ *>[ \t]?/gm, '');
@@ -162,7 +169,7 @@ export class Tokenizer {
162
169
  }
163
170
  }
164
171
 
165
- list(src) {
172
+ list(src: string): Tokens.List | undefined {
166
173
  let cap = this.rules.block.list.exec(src);
167
174
  if (cap) {
168
175
  let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine,
@@ -171,13 +178,13 @@ export class Tokenizer {
171
178
  let bull = cap[1].trim();
172
179
  const isordered = bull.length > 1;
173
180
 
174
- const list = {
181
+ const list: Tokens.List = {
175
182
  type: 'list',
176
183
  raw: '',
177
184
  ordered: isordered,
178
185
  start: isordered ? +bull.slice(0, -1) : '',
179
186
  loose: false,
180
- items: []
187
+ items: [] as Tokens.ListItem[]
181
188
  };
182
189
 
183
190
  bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
@@ -203,7 +210,7 @@ export class Tokenizer {
203
210
  raw = cap[0];
204
211
  src = src.substring(raw.length);
205
212
 
206
- line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
213
+ line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t: string) => ' '.repeat(3 * t.length));
207
214
  nextLine = src.split('\n', 1)[0];
208
215
 
209
216
  if (this.options.pedantic) {
@@ -327,7 +334,7 @@ export class Tokenizer {
327
334
 
328
335
  // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
329
336
  list.items[list.items.length - 1].raw = raw.trimRight();
330
- list.items[list.items.length - 1].text = itemContents.trimRight();
337
+ (list.items[list.items.length - 1] as Tokens.ListItem).text = itemContents.trimRight();
331
338
  list.raw = list.raw.trimRight();
332
339
 
333
340
  const l = list.items.length;
@@ -339,8 +346,8 @@ export class Tokenizer {
339
346
 
340
347
  if (!list.loose) {
341
348
  // Check if list should be loose
342
- const spacers = list.items[i].tokens.filter(t => t.type === 'space');
343
- const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw));
349
+ const spacers = list.items[i].tokens!.filter(t => t.type === 'space');
350
+ const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw!));
344
351
 
345
352
  list.loose = hasMultipleLineBreaks;
346
353
  }
@@ -357,10 +364,10 @@ export class Tokenizer {
357
364
  }
358
365
  }
359
366
 
360
- html(src) {
367
+ html(src: string): Tokens.HTML | Tokens.Paragraph | undefined {
361
368
  const cap = this.rules.block.html.exec(src);
362
369
  if (cap) {
363
- const token = {
370
+ const token: Tokens.HTML | Tokens.Paragraph = {
364
371
  type: 'html',
365
372
  block: true,
366
373
  raw: cap[0],
@@ -370,15 +377,16 @@ export class Tokenizer {
370
377
  };
371
378
  if (this.options.sanitize) {
372
379
  const text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
373
- token.type = 'paragraph';
374
- token.text = text;
375
- token.tokens = this.lexer.inline(text);
380
+ const paragraph = token as unknown as Tokens.Paragraph;
381
+ paragraph.type = 'paragraph';
382
+ paragraph.text = text;
383
+ paragraph.tokens = this.lexer.inline(text);
376
384
  }
377
385
  return token;
378
386
  }
379
387
  }
380
388
 
381
- def(src) {
389
+ def(src: string): Tokens.Def | undefined {
382
390
  const cap = this.rules.block.def.exec(src);
383
391
  if (cap) {
384
392
  const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
@@ -394,12 +402,16 @@ export class Tokenizer {
394
402
  }
395
403
  }
396
404
 
397
- table(src) {
405
+ table(src: string): Tokens.Table | undefined {
398
406
  const cap = this.rules.block.table.exec(src);
399
407
  if (cap) {
400
- const item = {
408
+ const item: Tokens.Table = {
401
409
  type: 'table',
402
- header: splitCells(cap[1]).map(c => { return { text: c }; }),
410
+ // splitCells expects a number as second argument
411
+ // @ts-expect-error
412
+ header: splitCells(cap[1]).map(c => {
413
+ return { text: c };
414
+ }),
403
415
  align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
404
416
  rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
405
417
  };
@@ -410,11 +422,11 @@ export class Tokenizer {
410
422
  let l = item.align.length;
411
423
  let i, j, k, row;
412
424
  for (i = 0; i < l; i++) {
413
- if (/^ *-+: *$/.test(item.align[i])) {
425
+ if (/^ *-+: *$/.test(item.align[i]!)) {
414
426
  item.align[i] = 'right';
415
- } else if (/^ *:-+: *$/.test(item.align[i])) {
427
+ } else if (/^ *:-+: *$/.test(item.align[i]!)) {
416
428
  item.align[i] = 'center';
417
- } else if (/^ *:-+ *$/.test(item.align[i])) {
429
+ } else if (/^ *:-+ *$/.test(item.align[i]!)) {
418
430
  item.align[i] = 'left';
419
431
  } else {
420
432
  item.align[i] = null;
@@ -423,7 +435,9 @@ export class Tokenizer {
423
435
 
424
436
  l = item.rows.length;
425
437
  for (i = 0; i < l; i++) {
426
- item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { return { text: c }; });
438
+ item.rows[i] = splitCells(item.rows[i] as unknown as string, item.header.length).map(c => {
439
+ return { text: c };
440
+ });
427
441
  }
428
442
 
429
443
  // parse child tokens inside headers and cells
@@ -448,7 +462,7 @@ export class Tokenizer {
448
462
  }
449
463
  }
450
464
 
451
- lheading(src) {
465
+ lheading(src: string): Tokens.Heading | undefined {
452
466
  const cap = this.rules.block.lheading.exec(src);
453
467
  if (cap) {
454
468
  return {
@@ -461,7 +475,7 @@ export class Tokenizer {
461
475
  }
462
476
  }
463
477
 
464
- paragraph(src) {
478
+ paragraph(src: string): Tokens.Paragraph | undefined {
465
479
  const cap = this.rules.block.paragraph.exec(src);
466
480
  if (cap) {
467
481
  const text = cap[1].charAt(cap[1].length - 1) === '\n'
@@ -476,7 +490,7 @@ export class Tokenizer {
476
490
  }
477
491
  }
478
492
 
479
- text(src) {
493
+ text(src: string): Tokens.Text | undefined {
480
494
  const cap = this.rules.block.text.exec(src);
481
495
  if (cap) {
482
496
  return {
@@ -488,7 +502,7 @@ export class Tokenizer {
488
502
  }
489
503
  }
490
504
 
491
- escape(src) {
505
+ escape(src: string): Tokens.Escape | undefined {
492
506
  const cap = this.rules.inline.escape.exec(src);
493
507
  if (cap) {
494
508
  return {
@@ -499,7 +513,7 @@ export class Tokenizer {
499
513
  }
500
514
  }
501
515
 
502
- tag(src) {
516
+ tag(src: string): Tokens.Tag | undefined {
503
517
  const cap = this.rules.inline.tag.exec(src);
504
518
  if (cap) {
505
519
  if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
@@ -530,7 +544,7 @@ export class Tokenizer {
530
544
  }
531
545
  }
532
546
 
533
- link(src) {
547
+ link(src: string): Tokens.Link | Tokens.Image | undefined {
534
548
  const cap = this.rules.inline.link.exec(src);
535
549
  if (cap) {
536
550
  const trimmedUrl = cap[2].trim();
@@ -586,10 +600,10 @@ export class Tokenizer {
586
600
  }
587
601
  }
588
602
 
589
- reflink(src, links) {
603
+ reflink(src: string, links: Links): Tokens.Link | Tokens.Image | Tokens.Text | undefined {
590
604
  let cap;
591
605
  if ((cap = this.rules.inline.reflink.exec(src))
592
- || (cap = this.rules.inline.nolink.exec(src))) {
606
+ || (cap = this.rules.inline.nolink.exec(src))) {
593
607
  let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
594
608
  link = links[link.toLowerCase()];
595
609
  if (!link) {
@@ -604,7 +618,7 @@ export class Tokenizer {
604
618
  }
605
619
  }
606
620
 
607
- emStrong(src, maskedSrc, prevChar = '') {
621
+ emStrong(src: string, maskedSrc: string, prevChar = ''): Tokens.Em | Tokens.Strong | undefined {
608
622
  let match = this.rules.inline.emStrong.lDelim.exec(src);
609
623
  if (!match) return;
610
624
 
@@ -672,7 +686,7 @@ export class Tokenizer {
672
686
  }
673
687
  }
674
688
 
675
- codespan(src) {
689
+ codespan(src: string): Tokens.Codespan | undefined {
676
690
  const cap = this.rules.inline.code.exec(src);
677
691
  if (cap) {
678
692
  let text = cap[2].replace(/\n/g, ' ');
@@ -690,7 +704,7 @@ export class Tokenizer {
690
704
  }
691
705
  }
692
706
 
693
- br(src) {
707
+ br(src: string): Tokens.Br | undefined {
694
708
  const cap = this.rules.inline.br.exec(src);
695
709
  if (cap) {
696
710
  return {
@@ -700,7 +714,7 @@ export class Tokenizer {
700
714
  }
701
715
  }
702
716
 
703
- del(src) {
717
+ del(src: string): Tokens.Del | undefined {
704
718
  const cap = this.rules.inline.del.exec(src);
705
719
  if (cap) {
706
720
  return {
@@ -712,7 +726,7 @@ export class Tokenizer {
712
726
  }
713
727
  }
714
728
 
715
- autolink(src, mangle) {
729
+ autolink(src: string, mangle: (cap: string) => string): Tokens.Link | undefined {
716
730
  const cap = this.rules.inline.autolink.exec(src);
717
731
  if (cap) {
718
732
  let text, href;
@@ -740,7 +754,7 @@ export class Tokenizer {
740
754
  }
741
755
  }
742
756
 
743
- url(src, mangle) {
757
+ url(src: string, mangle: (cap: string) => string): Tokens.Link | undefined {
744
758
  let cap;
745
759
  if (cap = this.rules.inline.url.exec(src)) {
746
760
  let text, href;
@@ -777,7 +791,7 @@ export class Tokenizer {
777
791
  }
778
792
  }
779
793
 
780
- inlineText(src, smartypants) {
794
+ inlineText(src: string, smartypants: (cap: string) => string): Tokens.Text | undefined {
781
795
  const cap = this.rules.inline.text.exec(src);
782
796
  if (cap) {
783
797
  let text;
package/src/Tokens.ts ADDED
@@ -0,0 +1,199 @@
1
+ /* eslint-disable no-use-before-define */
2
+ export type Token = (Tokens.Space
3
+ | Tokens.Code
4
+ | Tokens.Heading
5
+ | Tokens.Table
6
+ | Tokens.Hr
7
+ | Tokens.Blockquote
8
+ | Tokens.List
9
+ | Tokens.ListItem
10
+ | Tokens.Paragraph
11
+ | Tokens.HTML
12
+ | Tokens.Text
13
+ | Tokens.Def
14
+ | Tokens.Escape
15
+ | Tokens.Tag
16
+ | Tokens.Image
17
+ | Tokens.Link
18
+ | Tokens.Strong
19
+ | Tokens.Em
20
+ | Tokens.Codespan
21
+ | Tokens.Br
22
+ | Tokens.Del) & { loose?: boolean, tokens?: Token[] };
23
+
24
+ export namespace Tokens {
25
+ export interface Space {
26
+ type: 'space';
27
+ raw: string;
28
+ }
29
+
30
+ export interface Code {
31
+ type: 'code';
32
+ raw: string;
33
+ codeBlockStyle?: 'indented' | undefined;
34
+ lang?: string | undefined;
35
+ text: string;
36
+ escaped?: boolean;
37
+ }
38
+
39
+ export interface Heading {
40
+ type: 'heading';
41
+ raw: string;
42
+ depth: number;
43
+ text: string;
44
+ tokens: Token[];
45
+ }
46
+
47
+ export interface Table {
48
+ type: 'table';
49
+ raw?: string;
50
+ align: Array<'center' | 'left' | 'right' | null>;
51
+ header: TableCell[];
52
+ rows: TableCell[][];
53
+ }
54
+
55
+ export interface TableCell {
56
+ text: string;
57
+ tokens?: Token[];
58
+ }
59
+
60
+ export interface Hr {
61
+ type: 'hr';
62
+ raw: string;
63
+ }
64
+
65
+ export interface Blockquote {
66
+ type: 'blockquote';
67
+ raw: string;
68
+ text: string;
69
+ tokens: Token[];
70
+ }
71
+
72
+ export interface List {
73
+ type: 'list';
74
+ raw: string;
75
+ ordered: boolean;
76
+ start: number | '';
77
+ loose: boolean;
78
+ items: ListItem[];
79
+ }
80
+
81
+ export interface ListItem {
82
+ type: 'list_item';
83
+ raw: string;
84
+ task: boolean;
85
+ checked?: boolean | undefined;
86
+ loose: boolean;
87
+ text: string;
88
+ tokens?: Token[];
89
+ }
90
+
91
+ export interface Paragraph {
92
+ type: 'paragraph';
93
+ raw: string;
94
+ pre?: boolean | undefined;
95
+ text: string;
96
+ tokens: Token[];
97
+ }
98
+
99
+ export interface HTML {
100
+ type: 'html';
101
+ raw: string;
102
+ pre: boolean;
103
+ text: string;
104
+ block: boolean;
105
+ }
106
+
107
+ export interface Text {
108
+ type: 'text';
109
+ raw: string;
110
+ text: string;
111
+ tokens?: Token[];
112
+ }
113
+
114
+ export interface Def {
115
+ type: 'def';
116
+ raw: string;
117
+ tag: string;
118
+ href: string;
119
+ title: string;
120
+ }
121
+
122
+ export interface Escape {
123
+ type: 'escape';
124
+ raw: string;
125
+ text: string;
126
+ }
127
+
128
+ export interface Tag {
129
+ type: 'text' | 'html';
130
+ raw: string;
131
+ inLink: boolean;
132
+ inRawBlock: boolean;
133
+ text: string;
134
+ block: boolean;
135
+ }
136
+
137
+ export interface Link {
138
+ type: 'link';
139
+ raw: string;
140
+ href: string;
141
+ title?: string | null;
142
+ text: string;
143
+ tokens: Token[];
144
+ }
145
+
146
+ export interface Image {
147
+ type: 'image';
148
+ raw: string;
149
+ href: string;
150
+ title: string | null;
151
+ text: string;
152
+ }
153
+
154
+ export interface Strong {
155
+ type: 'strong';
156
+ raw: string;
157
+ text: string;
158
+ tokens: Token[];
159
+ }
160
+
161
+ export interface Em {
162
+ type: 'em';
163
+ raw: string;
164
+ text: string;
165
+ tokens: Token[];
166
+ }
167
+
168
+ export interface Codespan {
169
+ type: 'codespan';
170
+ raw: string;
171
+ text: string;
172
+ }
173
+
174
+ export interface Br {
175
+ type: 'br';
176
+ raw: string;
177
+ }
178
+
179
+ export interface Del {
180
+ type: 'del';
181
+ raw: string;
182
+ text: string;
183
+ tokens: Token[];
184
+ }
185
+
186
+ export interface Generic {
187
+ [index: string]: any;
188
+
189
+ type: string;
190
+ raw: string;
191
+ tokens?: Token[] | undefined;
192
+ }
193
+ }
194
+
195
+ export type Links = Record<string, Pick<Tokens.Link | Tokens.Image, 'href' | 'title'>>;
196
+
197
+ export type TokensList = Token[] & {
198
+ links: Links;
199
+ };
@@ -1,16 +1,21 @@
1
- export function getDefaults() {
1
+ import type { MarkedOptions } from './MarkedOptions.ts';
2
+
3
+ /**
4
+ * Gets the original marked default options.
5
+ */
6
+ export function _getDefaults(): MarkedOptions {
2
7
  return {
3
8
  async: false,
4
9
  baseUrl: null,
5
10
  breaks: false,
6
11
  extensions: null,
7
12
  gfm: true,
8
- headerIds: true,
13
+ headerIds: false,
9
14
  headerPrefix: '',
10
15
  highlight: null,
11
16
  hooks: null,
12
17
  langPrefix: 'language-',
13
- mangle: true,
18
+ mangle: false,
14
19
  pedantic: false,
15
20
  renderer: null,
16
21
  sanitize: false,
@@ -23,8 +28,8 @@ export function getDefaults() {
23
28
  };
24
29
  }
25
30
 
26
- export let defaults = getDefaults();
31
+ export let _defaults = _getDefaults();
27
32
 
28
- export function changeDefaults(newDefaults) {
29
- defaults = newDefaults;
33
+ export function changeDefaults(newDefaults: MarkedOptions) {
34
+ _defaults = newDefaults;
30
35
  }