@mdit-vue/shared 2.1.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,118 +1,118 @@
1
- 'use strict';
2
1
 
2
+ //#region src/html-escape.ts
3
3
  const htmlEscapeMap = {
4
- "&": "&",
5
- "<": "&lt;",
6
- ">": "&gt;",
7
- "'": "&#39;",
8
- '"': "&quot;"
4
+ "&": "&amp;",
5
+ "<": "&lt;",
6
+ ">": "&gt;",
7
+ "'": "&#39;",
8
+ "\"": "&quot;"
9
9
  };
10
10
  const htmlEscapeRegexp = /[&<>'"]/g;
11
- const htmlEscape = (str) => str.replace(
12
- htmlEscapeRegexp,
13
- (char) => htmlEscapeMap[char]
14
- );
11
+ /**
12
+ * Escape html chars
13
+ */
14
+ const htmlEscape = (str) => str.replace(htmlEscapeRegexp, (char) => htmlEscapeMap[char]);
15
15
 
16
+ //#endregion
17
+ //#region src/html-unescape.ts
16
18
  const htmlUnescapeMap = {
17
- "&amp;": "&",
18
- "&#38;": "&",
19
- "&lt;": "<",
20
- "&#60;": "<",
21
- "&gt;": ">",
22
- "&#62;": ">",
23
- "&apos;": "'",
24
- "&#39;": "'",
25
- "&quot;": '"',
26
- "&#34;": '"'
19
+ "&amp;": "&",
20
+ "&#38;": "&",
21
+ "&lt;": "<",
22
+ "&#60;": "<",
23
+ "&gt;": ">",
24
+ "&#62;": ">",
25
+ "&apos;": "'",
26
+ "&#39;": "'",
27
+ "&quot;": "\"",
28
+ "&#34;": "\""
27
29
  };
28
30
  const htmlUnescapeRegexp = /&(amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
29
- const htmlUnescape = (str) => str.replace(
30
- htmlUnescapeRegexp,
31
- (char) => htmlUnescapeMap[char]
32
- );
31
+ /**
32
+ * Unescape html chars
33
+ */
34
+ const htmlUnescape = (str) => str.replace(htmlUnescapeRegexp, (char) => htmlUnescapeMap[char]);
33
35
 
36
+ //#endregion
37
+ //#region src/resolve-title-from-token.ts
38
+ /**
39
+ * Resolve header title from markdown-it token
40
+ *
41
+ * Typically using the next token of `heading_open` token
42
+ */
34
43
  const resolveTitleFromToken = (token, { shouldAllowHtml, shouldEscapeText }) => {
35
- const children = token.children ?? [];
36
- const titleTokenTypes = ["text", "emoji", "code_inline"];
37
- if (shouldAllowHtml) {
38
- titleTokenTypes.push("html_inline");
39
- }
40
- const titleTokens = children.filter(
41
- (item) => titleTokenTypes.includes(item.type) && // filter permalink symbol that generated by markdown-it-anchor
42
- !item.meta?.isPermalinkSymbol
43
- );
44
- return titleTokens.reduce((result, item) => {
45
- if (shouldEscapeText) {
46
- if (item.type === "code_inline" || item.type === "text") {
47
- return `${result}${htmlEscape(item.content)}`;
48
- }
49
- }
50
- return `${result}${item.content}`;
51
- }, "").trim();
44
+ const children = token.children ?? [];
45
+ const titleTokenTypes = [
46
+ "text",
47
+ "emoji",
48
+ "code_inline"
49
+ ];
50
+ if (shouldAllowHtml) titleTokenTypes.push("html_inline");
51
+ const titleTokens = children.filter((item) => titleTokenTypes.includes(item.type) && !item.meta?.isPermalinkSymbol);
52
+ return titleTokens.reduce((result, item) => {
53
+ if (shouldEscapeText) {
54
+ if (item.type === "code_inline" || item.type === "text") return `${result}${htmlEscape(item.content)}`;
55
+ }
56
+ return `${result}${item.content}`;
57
+ }, "").trim();
52
58
  };
53
59
 
54
- const resolveHeadersFromTokens = (tokens, {
55
- level,
56
- shouldAllowHtml,
57
- shouldAllowNested,
58
- shouldEscapeText,
59
- slugify,
60
- format
61
- }) => {
62
- const headers = [];
63
- const stack = [];
64
- const push = (header) => {
65
- while (stack.length !== 0 && header.level <= stack[0].level) {
66
- stack.shift();
67
- }
68
- if (stack.length === 0) {
69
- headers.push(header);
70
- stack.push(header);
71
- } else {
72
- stack[0].children.push(header);
73
- stack.unshift(header);
74
- }
75
- };
76
- for (let i = 0; i < tokens.length; i += 1) {
77
- const token = tokens[i];
78
- if (token.type !== "heading_open") {
79
- continue;
80
- }
81
- if (token.level !== 0 && !shouldAllowNested) {
82
- continue;
83
- }
84
- const headerLevel = Number.parseInt(token.tag.slice(1), 10);
85
- if (!level.includes(headerLevel)) {
86
- continue;
87
- }
88
- const nextToken = tokens[i + 1];
89
- /* istanbul ignore if -- @preserve */
90
- if (!nextToken) {
91
- continue;
92
- }
93
- const title = resolveTitleFromToken(nextToken, {
94
- shouldAllowHtml,
95
- shouldEscapeText
96
- });
97
- const slug = token.attrGet("id") ?? slugify(title);
98
- push({
99
- level: headerLevel,
100
- title: format?.(title) ?? title,
101
- slug,
102
- link: `#${slug}`,
103
- children: []
104
- });
105
- }
106
- return headers;
60
+ //#endregion
61
+ //#region src/resolve-headers-from-tokens.ts
62
+ /**
63
+ * Resolve headers from markdown-it tokens
64
+ */
65
+ const resolveHeadersFromTokens = (tokens, { level, shouldAllowHtml, shouldAllowNested, shouldEscapeText, slugify: slugify$1, format }) => {
66
+ const headers = [];
67
+ const stack = [];
68
+ const push = (header) => {
69
+ while (stack.length !== 0 && header.level <= stack[0].level) stack.shift();
70
+ if (stack.length === 0) {
71
+ headers.push(header);
72
+ stack.push(header);
73
+ } else {
74
+ stack[0].children.push(header);
75
+ stack.unshift(header);
76
+ }
77
+ };
78
+ for (let i = 0; i < tokens.length; i += 1) {
79
+ const token = tokens[i];
80
+ if (token.type !== "heading_open") continue;
81
+ if (token.level !== 0 && !shouldAllowNested) continue;
82
+ const headerLevel = Number.parseInt(token.tag.slice(1), 10);
83
+ if (!level.includes(headerLevel)) continue;
84
+ const nextToken = tokens[i + 1];
85
+ /* istanbul ignore if -- @preserve */
86
+ if (!nextToken) continue;
87
+ const title = resolveTitleFromToken(nextToken, {
88
+ shouldAllowHtml,
89
+ shouldEscapeText
90
+ });
91
+ const slug = token.attrGet("id") ?? slugify$1(title);
92
+ push({
93
+ level: headerLevel,
94
+ title: format?.(title) ?? title,
95
+ slug,
96
+ link: `#${slug}`,
97
+ children: []
98
+ });
99
+ }
100
+ return headers;
107
101
  };
108
102
 
103
+ //#endregion
104
+ //#region src/slugify.ts
109
105
  const rControl = /[\u0000-\u001f]/g;
110
106
  const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g;
111
107
  const rCombining = /[\u0300-\u036F]/g;
108
+ /**
109
+ * Default slugification function
110
+ */
112
111
  const slugify = (str) => str.normalize("NFKD").replace(rCombining, "").replace(rControl, "").replace(rSpecial, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "").replace(/^(\d)/, "_$1").toLowerCase();
113
112
 
113
+ //#endregion
114
114
  exports.htmlEscape = htmlEscape;
115
115
  exports.htmlUnescape = htmlUnescape;
116
116
  exports.resolveHeadersFromTokens = resolveHeadersFromTokens;
117
117
  exports.resolveTitleFromToken = resolveTitleFromToken;
118
- exports.slugify = slugify;
118
+ exports.slugify = slugify;
package/dist/index.d.cts CHANGED
@@ -1,69 +1,84 @@
1
- import { MarkdownItHeader } from '@mdit-vue/types';
2
- import Token from 'markdown-it/lib/token.mjs';
1
+ import { MarkdownItHeader } from "@mdit-vue/types";
2
+ import Token from "markdown-it/lib/token.mjs";
3
3
 
4
+ //#region src/html-escape.d.ts
4
5
  /**
5
6
  * Escape html chars
6
7
  */
7
8
  declare const htmlEscape: (str: string) => string;
8
-
9
+ //#endregion
10
+ //#region src/html-unescape.d.ts
9
11
  /**
10
12
  * Unescape html chars
11
13
  */
12
14
  declare const htmlUnescape: (str: string) => string;
13
-
15
+ //#endregion
16
+ //#region src/resolve-title-from-token.d.ts
14
17
  interface ResolveTitleOptions {
15
- /**
16
- * Should allow inline HTML tags or not.
17
- *
18
- * If the result is going to be used as Vue template, it should allow inline
19
- * HTML tags so that Vue custom components would be kept.
20
- */
21
- shouldAllowHtml: boolean;
22
- /**
23
- * Should escape the text content or not.
24
- *
25
- * If the result is going to be used in HTML directly, it should be escaped
26
- * so that the text content won't be wrongly treated as HTML tags.
27
- */
28
- shouldEscapeText: boolean;
18
+ /**
19
+ * Should allow inline HTML tags or not.
20
+ *
21
+ * If the result is going to be used as Vue template, it should allow inline
22
+ * HTML tags so that Vue custom components would be kept.
23
+ */
24
+ shouldAllowHtml: boolean;
25
+ /**
26
+ * Should escape the text content or not.
27
+ *
28
+ * If the result is going to be used in HTML directly, it should be escaped
29
+ * so that the text content won't be wrongly treated as HTML tags.
30
+ */
31
+ shouldEscapeText: boolean;
29
32
  }
30
33
  /**
31
34
  * Resolve header title from markdown-it token
32
35
  *
33
36
  * Typically using the next token of `heading_open` token
34
37
  */
35
- declare const resolveTitleFromToken: (token: Token, { shouldAllowHtml, shouldEscapeText }: ResolveTitleOptions) => string;
36
-
38
+ declare const resolveTitleFromToken: (token: Token, {
39
+ shouldAllowHtml,
40
+ shouldEscapeText
41
+ }: ResolveTitleOptions) => string;
42
+ //#endregion
43
+ //#region src/resolve-headers-from-tokens.d.ts
37
44
  interface ResolveHeadersOptions extends ResolveTitleOptions {
38
- /**
39
- * Heading level that going to be resolved
40
- */
41
- level: number[];
42
- /**
43
- * Should allow headers inside nested blocks or not
44
- *
45
- * If set to `true`, headers inside blockquote, list, etc. would also be resolved.
46
- */
47
- shouldAllowNested: boolean;
48
- /**
49
- * A custom slugification function
50
- *
51
- * Would be ignored if the `id` attr of the token is set.
52
- */
53
- slugify: (str: string) => string;
54
- /**
55
- * A function for formatting headings
56
- */
57
- format?: (str: string) => string;
45
+ /**
46
+ * Heading level that going to be resolved
47
+ */
48
+ level: number[];
49
+ /**
50
+ * Should allow headers inside nested blocks or not
51
+ *
52
+ * If set to `true`, headers inside blockquote, list, etc. would also be resolved.
53
+ */
54
+ shouldAllowNested: boolean;
55
+ /**
56
+ * A custom slugification function
57
+ *
58
+ * Would be ignored if the `id` attr of the token is set.
59
+ */
60
+ slugify: (str: string) => string;
61
+ /**
62
+ * A function for formatting headings
63
+ */
64
+ format?: (str: string) => string;
58
65
  }
59
66
  /**
60
67
  * Resolve headers from markdown-it tokens
61
68
  */
62
- declare const resolveHeadersFromTokens: (tokens: Token[], { level, shouldAllowHtml, shouldAllowNested, shouldEscapeText, slugify, format, }: ResolveHeadersOptions) => MarkdownItHeader[];
63
-
69
+ declare const resolveHeadersFromTokens: (tokens: Token[], {
70
+ level,
71
+ shouldAllowHtml,
72
+ shouldAllowNested,
73
+ shouldEscapeText,
74
+ slugify,
75
+ format
76
+ }: ResolveHeadersOptions) => MarkdownItHeader[];
77
+ //#endregion
78
+ //#region src/slugify.d.ts
64
79
  /**
65
80
  * Default slugification function
66
81
  */
67
- declare const slugify: (str: string) => string;
68
-
69
- export { type ResolveHeadersOptions, type ResolveTitleOptions, htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify };
82
+ declare const slugify$1: (str: string) => string;
83
+ //#endregion
84
+ export { ResolveHeadersOptions, ResolveTitleOptions, htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify$1 as slugify };
package/dist/index.d.mts CHANGED
@@ -1,69 +1,84 @@
1
- import { MarkdownItHeader } from '@mdit-vue/types';
2
- import Token from 'markdown-it/lib/token.mjs';
1
+ import { MarkdownItHeader } from "@mdit-vue/types";
2
+ import Token from "markdown-it/lib/token.mjs";
3
3
 
4
+ //#region src/html-escape.d.ts
4
5
  /**
5
6
  * Escape html chars
6
7
  */
7
8
  declare const htmlEscape: (str: string) => string;
8
-
9
+ //#endregion
10
+ //#region src/html-unescape.d.ts
9
11
  /**
10
12
  * Unescape html chars
11
13
  */
12
14
  declare const htmlUnescape: (str: string) => string;
13
-
15
+ //#endregion
16
+ //#region src/resolve-title-from-token.d.ts
14
17
  interface ResolveTitleOptions {
15
- /**
16
- * Should allow inline HTML tags or not.
17
- *
18
- * If the result is going to be used as Vue template, it should allow inline
19
- * HTML tags so that Vue custom components would be kept.
20
- */
21
- shouldAllowHtml: boolean;
22
- /**
23
- * Should escape the text content or not.
24
- *
25
- * If the result is going to be used in HTML directly, it should be escaped
26
- * so that the text content won't be wrongly treated as HTML tags.
27
- */
28
- shouldEscapeText: boolean;
18
+ /**
19
+ * Should allow inline HTML tags or not.
20
+ *
21
+ * If the result is going to be used as Vue template, it should allow inline
22
+ * HTML tags so that Vue custom components would be kept.
23
+ */
24
+ shouldAllowHtml: boolean;
25
+ /**
26
+ * Should escape the text content or not.
27
+ *
28
+ * If the result is going to be used in HTML directly, it should be escaped
29
+ * so that the text content won't be wrongly treated as HTML tags.
30
+ */
31
+ shouldEscapeText: boolean;
29
32
  }
30
33
  /**
31
34
  * Resolve header title from markdown-it token
32
35
  *
33
36
  * Typically using the next token of `heading_open` token
34
37
  */
35
- declare const resolveTitleFromToken: (token: Token, { shouldAllowHtml, shouldEscapeText }: ResolveTitleOptions) => string;
36
-
38
+ declare const resolveTitleFromToken: (token: Token, {
39
+ shouldAllowHtml,
40
+ shouldEscapeText
41
+ }: ResolveTitleOptions) => string;
42
+ //#endregion
43
+ //#region src/resolve-headers-from-tokens.d.ts
37
44
  interface ResolveHeadersOptions extends ResolveTitleOptions {
38
- /**
39
- * Heading level that going to be resolved
40
- */
41
- level: number[];
42
- /**
43
- * Should allow headers inside nested blocks or not
44
- *
45
- * If set to `true`, headers inside blockquote, list, etc. would also be resolved.
46
- */
47
- shouldAllowNested: boolean;
48
- /**
49
- * A custom slugification function
50
- *
51
- * Would be ignored if the `id` attr of the token is set.
52
- */
53
- slugify: (str: string) => string;
54
- /**
55
- * A function for formatting headings
56
- */
57
- format?: (str: string) => string;
45
+ /**
46
+ * Heading level that going to be resolved
47
+ */
48
+ level: number[];
49
+ /**
50
+ * Should allow headers inside nested blocks or not
51
+ *
52
+ * If set to `true`, headers inside blockquote, list, etc. would also be resolved.
53
+ */
54
+ shouldAllowNested: boolean;
55
+ /**
56
+ * A custom slugification function
57
+ *
58
+ * Would be ignored if the `id` attr of the token is set.
59
+ */
60
+ slugify: (str: string) => string;
61
+ /**
62
+ * A function for formatting headings
63
+ */
64
+ format?: (str: string) => string;
58
65
  }
59
66
  /**
60
67
  * Resolve headers from markdown-it tokens
61
68
  */
62
- declare const resolveHeadersFromTokens: (tokens: Token[], { level, shouldAllowHtml, shouldAllowNested, shouldEscapeText, slugify, format, }: ResolveHeadersOptions) => MarkdownItHeader[];
63
-
69
+ declare const resolveHeadersFromTokens: (tokens: Token[], {
70
+ level,
71
+ shouldAllowHtml,
72
+ shouldAllowNested,
73
+ shouldEscapeText,
74
+ slugify,
75
+ format
76
+ }: ResolveHeadersOptions) => MarkdownItHeader[];
77
+ //#endregion
78
+ //#region src/slugify.d.ts
64
79
  /**
65
80
  * Default slugification function
66
81
  */
67
- declare const slugify: (str: string) => string;
68
-
69
- export { type ResolveHeadersOptions, type ResolveTitleOptions, htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify };
82
+ declare const slugify$1: (str: string) => string;
83
+ //#endregion
84
+ export { ResolveHeadersOptions, ResolveTitleOptions, htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify$1 as slugify };
package/dist/index.d.ts CHANGED
@@ -66,4 +66,5 @@ declare const resolveHeadersFromTokens: (tokens: Token[], { level, shouldAllowHt
66
66
  */
67
67
  declare const slugify: (str: string) => string;
68
68
 
69
- export { type ResolveHeadersOptions, type ResolveTitleOptions, htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify };
69
+ export { htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify };
70
+ export type { ResolveHeadersOptions, ResolveTitleOptions };
package/dist/index.mjs CHANGED
@@ -1,112 +1,113 @@
1
+ //#region src/html-escape.ts
1
2
  const htmlEscapeMap = {
2
- "&": "&amp;",
3
- "<": "&lt;",
4
- ">": "&gt;",
5
- "'": "&#39;",
6
- '"': "&quot;"
3
+ "&": "&amp;",
4
+ "<": "&lt;",
5
+ ">": "&gt;",
6
+ "'": "&#39;",
7
+ "\"": "&quot;"
7
8
  };
8
9
  const htmlEscapeRegexp = /[&<>'"]/g;
9
- const htmlEscape = (str) => str.replace(
10
- htmlEscapeRegexp,
11
- (char) => htmlEscapeMap[char]
12
- );
10
+ /**
11
+ * Escape html chars
12
+ */
13
+ const htmlEscape = (str) => str.replace(htmlEscapeRegexp, (char) => htmlEscapeMap[char]);
13
14
 
15
+ //#endregion
16
+ //#region src/html-unescape.ts
14
17
  const htmlUnescapeMap = {
15
- "&amp;": "&",
16
- "&#38;": "&",
17
- "&lt;": "<",
18
- "&#60;": "<",
19
- "&gt;": ">",
20
- "&#62;": ">",
21
- "&apos;": "'",
22
- "&#39;": "'",
23
- "&quot;": '"',
24
- "&#34;": '"'
18
+ "&amp;": "&",
19
+ "&#38;": "&",
20
+ "&lt;": "<",
21
+ "&#60;": "<",
22
+ "&gt;": ">",
23
+ "&#62;": ">",
24
+ "&apos;": "'",
25
+ "&#39;": "'",
26
+ "&quot;": "\"",
27
+ "&#34;": "\""
25
28
  };
26
29
  const htmlUnescapeRegexp = /&(amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
27
- const htmlUnescape = (str) => str.replace(
28
- htmlUnescapeRegexp,
29
- (char) => htmlUnescapeMap[char]
30
- );
30
+ /**
31
+ * Unescape html chars
32
+ */
33
+ const htmlUnescape = (str) => str.replace(htmlUnescapeRegexp, (char) => htmlUnescapeMap[char]);
31
34
 
35
+ //#endregion
36
+ //#region src/resolve-title-from-token.ts
37
+ /**
38
+ * Resolve header title from markdown-it token
39
+ *
40
+ * Typically using the next token of `heading_open` token
41
+ */
32
42
  const resolveTitleFromToken = (token, { shouldAllowHtml, shouldEscapeText }) => {
33
- const children = token.children ?? [];
34
- const titleTokenTypes = ["text", "emoji", "code_inline"];
35
- if (shouldAllowHtml) {
36
- titleTokenTypes.push("html_inline");
37
- }
38
- const titleTokens = children.filter(
39
- (item) => titleTokenTypes.includes(item.type) && // filter permalink symbol that generated by markdown-it-anchor
40
- !item.meta?.isPermalinkSymbol
41
- );
42
- return titleTokens.reduce((result, item) => {
43
- if (shouldEscapeText) {
44
- if (item.type === "code_inline" || item.type === "text") {
45
- return `${result}${htmlEscape(item.content)}`;
46
- }
47
- }
48
- return `${result}${item.content}`;
49
- }, "").trim();
43
+ const children = token.children ?? [];
44
+ const titleTokenTypes = [
45
+ "text",
46
+ "emoji",
47
+ "code_inline"
48
+ ];
49
+ if (shouldAllowHtml) titleTokenTypes.push("html_inline");
50
+ const titleTokens = children.filter((item) => titleTokenTypes.includes(item.type) && !item.meta?.isPermalinkSymbol);
51
+ return titleTokens.reduce((result, item) => {
52
+ if (shouldEscapeText) {
53
+ if (item.type === "code_inline" || item.type === "text") return `${result}${htmlEscape(item.content)}`;
54
+ }
55
+ return `${result}${item.content}`;
56
+ }, "").trim();
50
57
  };
51
58
 
52
- const resolveHeadersFromTokens = (tokens, {
53
- level,
54
- shouldAllowHtml,
55
- shouldAllowNested,
56
- shouldEscapeText,
57
- slugify,
58
- format
59
- }) => {
60
- const headers = [];
61
- const stack = [];
62
- const push = (header) => {
63
- while (stack.length !== 0 && header.level <= stack[0].level) {
64
- stack.shift();
65
- }
66
- if (stack.length === 0) {
67
- headers.push(header);
68
- stack.push(header);
69
- } else {
70
- stack[0].children.push(header);
71
- stack.unshift(header);
72
- }
73
- };
74
- for (let i = 0; i < tokens.length; i += 1) {
75
- const token = tokens[i];
76
- if (token.type !== "heading_open") {
77
- continue;
78
- }
79
- if (token.level !== 0 && !shouldAllowNested) {
80
- continue;
81
- }
82
- const headerLevel = Number.parseInt(token.tag.slice(1), 10);
83
- if (!level.includes(headerLevel)) {
84
- continue;
85
- }
86
- const nextToken = tokens[i + 1];
87
- /* istanbul ignore if -- @preserve */
88
- if (!nextToken) {
89
- continue;
90
- }
91
- const title = resolveTitleFromToken(nextToken, {
92
- shouldAllowHtml,
93
- shouldEscapeText
94
- });
95
- const slug = token.attrGet("id") ?? slugify(title);
96
- push({
97
- level: headerLevel,
98
- title: format?.(title) ?? title,
99
- slug,
100
- link: `#${slug}`,
101
- children: []
102
- });
103
- }
104
- return headers;
59
+ //#endregion
60
+ //#region src/resolve-headers-from-tokens.ts
61
+ /**
62
+ * Resolve headers from markdown-it tokens
63
+ */
64
+ const resolveHeadersFromTokens = (tokens, { level, shouldAllowHtml, shouldAllowNested, shouldEscapeText, slugify: slugify$1, format }) => {
65
+ const headers = [];
66
+ const stack = [];
67
+ const push = (header) => {
68
+ while (stack.length !== 0 && header.level <= stack[0].level) stack.shift();
69
+ if (stack.length === 0) {
70
+ headers.push(header);
71
+ stack.push(header);
72
+ } else {
73
+ stack[0].children.push(header);
74
+ stack.unshift(header);
75
+ }
76
+ };
77
+ for (let i = 0; i < tokens.length; i += 1) {
78
+ const token = tokens[i];
79
+ if (token.type !== "heading_open") continue;
80
+ if (token.level !== 0 && !shouldAllowNested) continue;
81
+ const headerLevel = Number.parseInt(token.tag.slice(1), 10);
82
+ if (!level.includes(headerLevel)) continue;
83
+ const nextToken = tokens[i + 1];
84
+ /* istanbul ignore if -- @preserve */
85
+ if (!nextToken) continue;
86
+ const title = resolveTitleFromToken(nextToken, {
87
+ shouldAllowHtml,
88
+ shouldEscapeText
89
+ });
90
+ const slug = token.attrGet("id") ?? slugify$1(title);
91
+ push({
92
+ level: headerLevel,
93
+ title: format?.(title) ?? title,
94
+ slug,
95
+ link: `#${slug}`,
96
+ children: []
97
+ });
98
+ }
99
+ return headers;
105
100
  };
106
101
 
102
+ //#endregion
103
+ //#region src/slugify.ts
107
104
  const rControl = /[\u0000-\u001f]/g;
108
105
  const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g;
109
106
  const rCombining = /[\u0300-\u036F]/g;
107
+ /**
108
+ * Default slugification function
109
+ */
110
110
  const slugify = (str) => str.normalize("NFKD").replace(rCombining, "").replace(rControl, "").replace(rSpecial, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "").replace(/^(\d)/, "_$1").toLowerCase();
111
111
 
112
- export { htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify };
112
+ //#endregion
113
+ export { htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolveTitleFromToken, slugify };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mdit-vue/shared",
3
- "version": "2.1.3",
3
+ "version": "3.0.0",
4
4
  "description": "Shared utils and types of mdit-vue",
5
5
  "keywords": [
6
6
  "markdown-it",
@@ -20,33 +20,35 @@
20
20
  "type": "module",
21
21
  "exports": {
22
22
  ".": {
23
- "import": {
24
- "types": "./dist/index.d.mts",
25
- "default": "./dist/index.mjs"
26
- },
27
- "require": {
28
- "types": "./dist/index.d.cts",
29
- "default": "./dist/index.cjs"
30
- }
31
- }
23
+ "import": "./dist/index.mjs",
24
+ "require": "./dist/index.cjs"
25
+ },
26
+ "./package.json": "./package.json"
32
27
  },
33
28
  "main": "./dist/index.cjs",
34
29
  "module": "./dist/index.mjs",
35
- "types": "./dist/index.d.ts",
30
+ "types": "./dist/index.d.cts",
36
31
  "files": [
37
32
  "./dist"
38
33
  ],
39
34
  "scripts": {
40
- "build": "unbuild",
35
+ "build": "tsdown",
41
36
  "test": "vitest"
42
37
  },
43
38
  "dependencies": {
44
- "@mdit-vue/types": "2.1.0",
45
- "@types/markdown-it": "^14.1.1",
39
+ "@mdit-vue/types": "3.0.0",
40
+ "@types/markdown-it": "^14.1.2",
46
41
  "markdown-it": "^14.1.0"
47
42
  },
43
+ "devDependencies": {
44
+ "tsdown": "^0.14.0",
45
+ "vitest": "^3.2.4"
46
+ },
47
+ "engines": {
48
+ "node": ">=20.0.0"
49
+ },
48
50
  "publishConfig": {
49
51
  "access": "public"
50
52
  },
51
- "gitHead": "0b0ff6922bba2627dad6b9cf0e4249f0a9ecbe15"
53
+ "gitHead": "bbb62a47109c2932505b3f570b963f70d590914f"
52
54
  }