@md-plugins/shared 0.1.0-rc.17 → 0.1.0-rc.19
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.d.mts +78 -81
- package/dist/index.d.ts +78 -81
- package/dist/index.mjs +78 -79
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,65 +1,59 @@
|
|
|
1
|
-
import Token from
|
|
2
|
-
|
|
1
|
+
import Token from "markdown-it/lib/token.mjs";
|
|
3
2
|
/**
|
|
4
3
|
* Escapes HTML-sensitive characters so text can be safely injected into markup.
|
|
5
4
|
*/
|
|
6
5
|
declare const htmlEscape: (str: string) => string;
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* Decodes the HTML entities emitted by {@link htmlEscape} and common numeric variants.
|
|
10
8
|
*/
|
|
11
9
|
declare const htmlUnescape: (str: string) => string;
|
|
12
|
-
|
|
13
10
|
interface MarkdownItEnv {
|
|
14
|
-
|
|
11
|
+
plugins?: Record<string, unknown>;
|
|
15
12
|
}
|
|
16
13
|
interface MarkdownItHeader {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
14
|
+
/**
|
|
15
|
+
* The slug of the header
|
|
16
|
+
*
|
|
17
|
+
* Typically the `id` attr of the header anchor
|
|
18
|
+
*/
|
|
19
|
+
id: string;
|
|
20
|
+
/**
|
|
21
|
+
* The level of the header
|
|
22
|
+
*
|
|
23
|
+
* `1` to `6` for `<h1>` to `<h6>`
|
|
24
|
+
*/
|
|
25
|
+
level: number;
|
|
26
|
+
/**
|
|
27
|
+
* The title of the header
|
|
28
|
+
*/
|
|
29
|
+
title: string;
|
|
30
|
+
/**
|
|
31
|
+
* Link of the header
|
|
32
|
+
*
|
|
33
|
+
* Typically using `#${slug}` as the anchor hash
|
|
34
|
+
*/
|
|
35
|
+
link: string;
|
|
36
|
+
/**
|
|
37
|
+
* The children of the header
|
|
38
|
+
*/
|
|
39
|
+
children: MarkdownItHeader[];
|
|
43
40
|
}
|
|
44
|
-
type ResolvePluginOptionsFn = <T extends object, K extends keyof any>(options: T | {
|
|
45
|
-
[P in K]?: T;
|
|
46
|
-
} | undefined, key: K, defaults: T) => T;
|
|
47
|
-
|
|
41
|
+
type ResolvePluginOptionsFn = <T extends object, K extends keyof any>(options: T | { [P in K]?: T } | undefined, key: K, defaults: T) => T;
|
|
48
42
|
interface ResolveTitleOptions {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Should allow inline HTML tags or not.
|
|
45
|
+
*
|
|
46
|
+
* If the result is going to be used as Vue template, it should allow inline
|
|
47
|
+
* HTML tags so that Vue custom components would be kept.
|
|
48
|
+
*/
|
|
49
|
+
shouldAllowHtml: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Should escape the text content or not.
|
|
52
|
+
*
|
|
53
|
+
* If the result is going to be used in HTML directly, it should be escaped
|
|
54
|
+
* so that the text content won't be wrongly treated as HTML tags.
|
|
55
|
+
*/
|
|
56
|
+
shouldEscapeText: boolean;
|
|
63
57
|
}
|
|
64
58
|
/**
|
|
65
59
|
* Extracts plain heading text from a markdown-it inline token.
|
|
@@ -68,29 +62,31 @@ interface ResolveTitleOptions {
|
|
|
68
62
|
* `heading_open` token. Permalink marker tokens generated by markdown-it-anchor
|
|
69
63
|
* are ignored so the title remains human-readable.
|
|
70
64
|
*/
|
|
71
|
-
declare const resolveTitleFromToken: (token: Token, {
|
|
72
|
-
|
|
65
|
+
declare const resolveTitleFromToken: (token: Token, {
|
|
66
|
+
shouldAllowHtml,
|
|
67
|
+
shouldEscapeText
|
|
68
|
+
}: ResolveTitleOptions) => string;
|
|
73
69
|
interface ResolveHeadersOptions extends ResolveTitleOptions {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Heading level that going to be resolved
|
|
72
|
+
*/
|
|
73
|
+
level: number[];
|
|
74
|
+
/**
|
|
75
|
+
* Should allow headers inside nested blocks or not
|
|
76
|
+
*
|
|
77
|
+
* If set to `true`, headers inside blockquote, list, etc. would also be resolved.
|
|
78
|
+
*/
|
|
79
|
+
shouldAllowNested: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* A custom slugification function
|
|
82
|
+
*
|
|
83
|
+
* Would be ignored if the `id` attr of the token is set.
|
|
84
|
+
*/
|
|
85
|
+
slugify?: (str: string) => string;
|
|
86
|
+
/**
|
|
87
|
+
* A function for formatting headings
|
|
88
|
+
*/
|
|
89
|
+
format?: (str: string) => string | undefined;
|
|
94
90
|
}
|
|
95
91
|
/**
|
|
96
92
|
* Builds a nested heading tree from markdown-it heading tokens.
|
|
@@ -98,16 +94,21 @@ interface ResolveHeadersOptions extends ResolveTitleOptions {
|
|
|
98
94
|
* Existing heading `id` attributes are preserved. When a heading has no `id`,
|
|
99
95
|
* the configured `slugify` function creates one from the resolved heading text.
|
|
100
96
|
*/
|
|
101
|
-
declare const resolveHeadersFromTokens: (tokens: Token[], {
|
|
102
|
-
|
|
97
|
+
declare const resolveHeadersFromTokens: (tokens: Token[], {
|
|
98
|
+
level,
|
|
99
|
+
shouldAllowHtml,
|
|
100
|
+
shouldAllowNested,
|
|
101
|
+
shouldEscapeText,
|
|
102
|
+
slugify,
|
|
103
|
+
format
|
|
104
|
+
}?: Partial<ResolveHeadersOptions>) => MarkdownItHeader[];
|
|
103
105
|
/**
|
|
104
106
|
* Converts arbitrary heading text into a stable URL-friendly slug.
|
|
105
107
|
*
|
|
106
108
|
* The result is lowercase, accent-free, hyphen-separated, and safe to use as a
|
|
107
109
|
* generated Markdown heading id.
|
|
108
110
|
*/
|
|
109
|
-
declare const slugify: (str: string) => string;
|
|
110
|
-
|
|
111
|
+
declare const slugify$1: (str: string) => string;
|
|
111
112
|
/**
|
|
112
113
|
* Resolves plugin options from either a direct options object or a nested
|
|
113
114
|
* package-level options bag.
|
|
@@ -116,9 +117,5 @@ declare const slugify: (str: string) => string;
|
|
|
116
117
|
* or through a shared md-plugins config object keyed by plugin name. This helper
|
|
117
118
|
* supports both shapes while applying default values.
|
|
118
119
|
*/
|
|
119
|
-
declare function resolvePluginOptions<T extends object, K extends keyof any>(options: T | {
|
|
120
|
-
|
|
121
|
-
} | undefined, key: K, defaults: T): T;
|
|
122
|
-
|
|
123
|
-
export { htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolvePluginOptions, resolveTitleFromToken, slugify };
|
|
124
|
-
export type { MarkdownItEnv, MarkdownItHeader, ResolveHeadersOptions, ResolvePluginOptionsFn, ResolveTitleOptions };
|
|
120
|
+
declare function resolvePluginOptions<T extends object, K extends keyof any>(options: T | { [key in K]?: T } | undefined, key: K, defaults: T): T;
|
|
121
|
+
export { type MarkdownItEnv, type MarkdownItHeader, ResolveHeadersOptions, type ResolvePluginOptionsFn, ResolveTitleOptions, htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolvePluginOptions, resolveTitleFromToken, slugify$1 as slugify };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,65 +1,59 @@
|
|
|
1
|
-
import Token from
|
|
2
|
-
|
|
1
|
+
import Token from "markdown-it/lib/token.mjs";
|
|
3
2
|
/**
|
|
4
3
|
* Escapes HTML-sensitive characters so text can be safely injected into markup.
|
|
5
4
|
*/
|
|
6
5
|
declare const htmlEscape: (str: string) => string;
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* Decodes the HTML entities emitted by {@link htmlEscape} and common numeric variants.
|
|
10
8
|
*/
|
|
11
9
|
declare const htmlUnescape: (str: string) => string;
|
|
12
|
-
|
|
13
10
|
interface MarkdownItEnv {
|
|
14
|
-
|
|
11
|
+
plugins?: Record<string, unknown>;
|
|
15
12
|
}
|
|
16
13
|
interface MarkdownItHeader {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
14
|
+
/**
|
|
15
|
+
* The slug of the header
|
|
16
|
+
*
|
|
17
|
+
* Typically the `id` attr of the header anchor
|
|
18
|
+
*/
|
|
19
|
+
id: string;
|
|
20
|
+
/**
|
|
21
|
+
* The level of the header
|
|
22
|
+
*
|
|
23
|
+
* `1` to `6` for `<h1>` to `<h6>`
|
|
24
|
+
*/
|
|
25
|
+
level: number;
|
|
26
|
+
/**
|
|
27
|
+
* The title of the header
|
|
28
|
+
*/
|
|
29
|
+
title: string;
|
|
30
|
+
/**
|
|
31
|
+
* Link of the header
|
|
32
|
+
*
|
|
33
|
+
* Typically using `#${slug}` as the anchor hash
|
|
34
|
+
*/
|
|
35
|
+
link: string;
|
|
36
|
+
/**
|
|
37
|
+
* The children of the header
|
|
38
|
+
*/
|
|
39
|
+
children: MarkdownItHeader[];
|
|
43
40
|
}
|
|
44
|
-
type ResolvePluginOptionsFn = <T extends object, K extends keyof any>(options: T | {
|
|
45
|
-
[P in K]?: T;
|
|
46
|
-
} | undefined, key: K, defaults: T) => T;
|
|
47
|
-
|
|
41
|
+
type ResolvePluginOptionsFn = <T extends object, K extends keyof any>(options: T | { [P in K]?: T } | undefined, key: K, defaults: T) => T;
|
|
48
42
|
interface ResolveTitleOptions {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Should allow inline HTML tags or not.
|
|
45
|
+
*
|
|
46
|
+
* If the result is going to be used as Vue template, it should allow inline
|
|
47
|
+
* HTML tags so that Vue custom components would be kept.
|
|
48
|
+
*/
|
|
49
|
+
shouldAllowHtml: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Should escape the text content or not.
|
|
52
|
+
*
|
|
53
|
+
* If the result is going to be used in HTML directly, it should be escaped
|
|
54
|
+
* so that the text content won't be wrongly treated as HTML tags.
|
|
55
|
+
*/
|
|
56
|
+
shouldEscapeText: boolean;
|
|
63
57
|
}
|
|
64
58
|
/**
|
|
65
59
|
* Extracts plain heading text from a markdown-it inline token.
|
|
@@ -68,29 +62,31 @@ interface ResolveTitleOptions {
|
|
|
68
62
|
* `heading_open` token. Permalink marker tokens generated by markdown-it-anchor
|
|
69
63
|
* are ignored so the title remains human-readable.
|
|
70
64
|
*/
|
|
71
|
-
declare const resolveTitleFromToken: (token: Token, {
|
|
72
|
-
|
|
65
|
+
declare const resolveTitleFromToken: (token: Token, {
|
|
66
|
+
shouldAllowHtml,
|
|
67
|
+
shouldEscapeText
|
|
68
|
+
}: ResolveTitleOptions) => string;
|
|
73
69
|
interface ResolveHeadersOptions extends ResolveTitleOptions {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Heading level that going to be resolved
|
|
72
|
+
*/
|
|
73
|
+
level: number[];
|
|
74
|
+
/**
|
|
75
|
+
* Should allow headers inside nested blocks or not
|
|
76
|
+
*
|
|
77
|
+
* If set to `true`, headers inside blockquote, list, etc. would also be resolved.
|
|
78
|
+
*/
|
|
79
|
+
shouldAllowNested: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* A custom slugification function
|
|
82
|
+
*
|
|
83
|
+
* Would be ignored if the `id` attr of the token is set.
|
|
84
|
+
*/
|
|
85
|
+
slugify?: (str: string) => string;
|
|
86
|
+
/**
|
|
87
|
+
* A function for formatting headings
|
|
88
|
+
*/
|
|
89
|
+
format?: (str: string) => string | undefined;
|
|
94
90
|
}
|
|
95
91
|
/**
|
|
96
92
|
* Builds a nested heading tree from markdown-it heading tokens.
|
|
@@ -98,16 +94,21 @@ interface ResolveHeadersOptions extends ResolveTitleOptions {
|
|
|
98
94
|
* Existing heading `id` attributes are preserved. When a heading has no `id`,
|
|
99
95
|
* the configured `slugify` function creates one from the resolved heading text.
|
|
100
96
|
*/
|
|
101
|
-
declare const resolveHeadersFromTokens: (tokens: Token[], {
|
|
102
|
-
|
|
97
|
+
declare const resolveHeadersFromTokens: (tokens: Token[], {
|
|
98
|
+
level,
|
|
99
|
+
shouldAllowHtml,
|
|
100
|
+
shouldAllowNested,
|
|
101
|
+
shouldEscapeText,
|
|
102
|
+
slugify,
|
|
103
|
+
format
|
|
104
|
+
}?: Partial<ResolveHeadersOptions>) => MarkdownItHeader[];
|
|
103
105
|
/**
|
|
104
106
|
* Converts arbitrary heading text into a stable URL-friendly slug.
|
|
105
107
|
*
|
|
106
108
|
* The result is lowercase, accent-free, hyphen-separated, and safe to use as a
|
|
107
109
|
* generated Markdown heading id.
|
|
108
110
|
*/
|
|
109
|
-
declare const slugify: (str: string) => string;
|
|
110
|
-
|
|
111
|
+
declare const slugify$1: (str: string) => string;
|
|
111
112
|
/**
|
|
112
113
|
* Resolves plugin options from either a direct options object or a nested
|
|
113
114
|
* package-level options bag.
|
|
@@ -116,9 +117,5 @@ declare const slugify: (str: string) => string;
|
|
|
116
117
|
* or through a shared md-plugins config object keyed by plugin name. This helper
|
|
117
118
|
* supports both shapes while applying default values.
|
|
118
119
|
*/
|
|
119
|
-
declare function resolvePluginOptions<T extends object, K extends keyof any>(options: T | {
|
|
120
|
-
|
|
121
|
-
} | undefined, key: K, defaults: T): T;
|
|
122
|
-
|
|
123
|
-
export { htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolvePluginOptions, resolveTitleFromToken, slugify };
|
|
124
|
-
export type { MarkdownItEnv, MarkdownItHeader, ResolveHeadersOptions, ResolvePluginOptionsFn, ResolveTitleOptions };
|
|
120
|
+
declare function resolvePluginOptions<T extends object, K extends keyof any>(options: T | { [key in K]?: T } | undefined, key: K, defaults: T): T;
|
|
121
|
+
export { type MarkdownItEnv, type MarkdownItHeader, ResolveHeadersOptions, type ResolvePluginOptionsFn, ResolveTitleOptions, htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolvePluginOptions, resolveTitleFromToken, slugify$1 as slugify };
|
package/dist/index.mjs
CHANGED
|
@@ -1,103 +1,102 @@
|
|
|
1
1
|
const htmlEscapeMap = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"&": "&",
|
|
3
|
+
"<": "<",
|
|
4
|
+
">": ">",
|
|
5
|
+
"'": "'",
|
|
6
|
+
"\"": """
|
|
7
7
|
};
|
|
8
8
|
const htmlEscapeRegexp = /[&<>'"]/g;
|
|
9
|
+
|
|
9
10
|
const htmlEscape = (str) => str.replace(htmlEscapeRegexp, (char) => htmlEscapeMap[char]);
|
|
10
11
|
|
|
11
12
|
const htmlUnescapeMap = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
"&": "&",
|
|
14
|
+
"&": "&",
|
|
15
|
+
"<": "<",
|
|
16
|
+
"<": "<",
|
|
17
|
+
">": ">",
|
|
18
|
+
">": ">",
|
|
19
|
+
"'": "'",
|
|
20
|
+
"'": "'",
|
|
21
|
+
""": "\"",
|
|
22
|
+
""": "\""
|
|
22
23
|
};
|
|
23
24
|
const htmlUnescapeRegexp = /&(amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
|
|
25
|
+
|
|
24
26
|
const htmlUnescape = (str) => str.replace(htmlUnescapeRegexp, (char) => htmlUnescapeMap[char]);
|
|
25
27
|
|
|
28
|
+
|
|
26
29
|
const resolveTitleFromToken = (token, { shouldAllowHtml, shouldEscapeText }) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return `${result}${item.content}`;
|
|
43
|
-
}, "").trim();
|
|
30
|
+
const children = token.children ?? [];
|
|
31
|
+
const titleTokenTypes = [
|
|
32
|
+
"text",
|
|
33
|
+
"emoji",
|
|
34
|
+
"code_inline"
|
|
35
|
+
];
|
|
36
|
+
if (shouldAllowHtml) titleTokenTypes.push("html_inline");
|
|
37
|
+
return children.filter((item) => titleTokenTypes.includes(item.type) && !item.meta?.isPermalinkSymbol).reduce((result, item) => {
|
|
38
|
+
if (shouldEscapeText) {
|
|
39
|
+
if (item.type === "code_inline" || item.type === "text") return `${result}${htmlEscape(item.content)}`;
|
|
40
|
+
}
|
|
41
|
+
return `${result}${item.content}`;
|
|
42
|
+
}, "").trim();
|
|
44
43
|
};
|
|
45
44
|
|
|
46
45
|
const andRE = /&/g;
|
|
47
46
|
const rCombining = /[\u0300-\u036F]/g;
|
|
48
47
|
const rControl = /[\u0000-\u001f]/g;
|
|
49
48
|
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g;
|
|
49
|
+
|
|
50
50
|
const slugify = (str) => str.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase().normalize("NFKD").replace(rCombining, "").replace(andRE, "-and-").replace(rControl, "-").replace(rSpecial, "-").replace(/[^a-z0-9-]+/g, "").replace(/([a-z])(\d)/g, "$1-$2").replace(/(\d)([a-z])/g, "$1-$2").replace(/-{2,}/g, "-").replace(/(^-|-$)/g, "").replace(/^(\d)/, "_$1");
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
id: slug,
|
|
89
|
-
link: `#${slug}`,
|
|
90
|
-
children: []
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
return headers;
|
|
52
|
+
|
|
53
|
+
const resolveHeadersFromTokens = (tokens, { level = [
|
|
54
|
+
1,
|
|
55
|
+
2,
|
|
56
|
+
3
|
|
57
|
+
], shouldAllowHtml = false, shouldAllowNested = false, shouldEscapeText = false, slugify: slugify$1 = slugify, format = (str) => str } = {}) => {
|
|
58
|
+
const headers = [];
|
|
59
|
+
const stack = [];
|
|
60
|
+
|
|
61
|
+
const pushHeader = (header) => {
|
|
62
|
+
while (stack.length > 0 && header.level <= stack[0].level) stack.shift();
|
|
63
|
+
if (stack.length === 0) headers.push(header);
|
|
64
|
+
else stack[0].children.push(header);
|
|
65
|
+
stack.unshift(header);
|
|
66
|
+
};
|
|
67
|
+
tokens.forEach((token, i) => {
|
|
68
|
+
if (token.type !== "heading_open") return;
|
|
69
|
+
if (token.level !== 0 && !shouldAllowNested) return;
|
|
70
|
+
const headerLevel = Number.parseInt(token.tag.slice(1), 10);
|
|
71
|
+
if (!level.includes(headerLevel)) return;
|
|
72
|
+
const nextToken = tokens[i + 1];
|
|
73
|
+
if (!nextToken) return;
|
|
74
|
+
const title = resolveTitleFromToken(nextToken, {
|
|
75
|
+
shouldAllowHtml,
|
|
76
|
+
shouldEscapeText
|
|
77
|
+
});
|
|
78
|
+
const slug = token.attrGet("id") ?? slugify$1(title);
|
|
79
|
+
pushHeader({
|
|
80
|
+
level: headerLevel,
|
|
81
|
+
title: format(title) ?? title,
|
|
82
|
+
id: slug,
|
|
83
|
+
link: `#${slug}`,
|
|
84
|
+
children: []
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
return headers;
|
|
94
88
|
};
|
|
95
89
|
|
|
90
|
+
|
|
96
91
|
function resolvePluginOptions(options, key, defaults) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
if (options && typeof options === "object" && key in options) return {
|
|
93
|
+
...defaults,
|
|
94
|
+
...options[key]
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
...defaults,
|
|
98
|
+
...options
|
|
99
|
+
};
|
|
101
100
|
}
|
|
102
101
|
|
|
103
|
-
export { htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolvePluginOptions, resolveTitleFromToken, slugify };
|
|
102
|
+
export { htmlEscape, htmlUnescape, resolveHeadersFromTokens, resolvePluginOptions, resolveTitleFromToken, slugify };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@md-plugins/shared",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.19",
|
|
4
4
|
"description": "Shared functions and utilities for md-plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown-it",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"markdown-it": "^14.2.0"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
|
-
"build": "
|
|
46
|
+
"build": "obuild && node ../../scripts/ensure-obuild-types.mjs",
|
|
47
47
|
"clean": "rm -rf dist/ node_modules/",
|
|
48
48
|
"test": "vitest"
|
|
49
49
|
}
|