@md-plugins/md-plugin-headers 0.1.0-alpha.9 → 0.1.0-beta.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/README.md +9 -5
- package/dist/index.d.mts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.mjs +60 -38
- package/package.json +15 -17
package/README.md
CHANGED
|
@@ -17,12 +17,12 @@ A **Markdown-It** plugin that extracts and processes headers from Markdown conte
|
|
|
17
17
|
Install the plugin via your preferred package manager:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
#
|
|
21
|
-
npm install @md-plugins/md-plugin-headers
|
|
22
|
-
# Or with Yarn:
|
|
23
|
-
yarn add @md-plugins/md-plugin-headers
|
|
24
|
-
# Or with pnpm:
|
|
20
|
+
# with pnpm:
|
|
25
21
|
pnpm add @md-plugins/md-plugin-headers
|
|
22
|
+
# with Yarn:
|
|
23
|
+
yarn add @md-plugins/md-plugin-headers
|
|
24
|
+
# with npm:
|
|
25
|
+
npm install @md-plugins/md-plugin-headers
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Usage
|
|
@@ -148,6 +148,10 @@ md.use(headersPlugin, {
|
|
|
148
148
|
pnpm test
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
+
## Documentation
|
|
152
|
+
|
|
153
|
+
In case this README falls out of date, please refer to the [documentation](https://md-plugins.netlify.app/md-plugins/headers/overview) for the latest information.
|
|
154
|
+
|
|
151
155
|
## License
|
|
152
156
|
|
|
153
157
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details.
|
package/dist/index.d.mts
CHANGED
|
@@ -32,6 +32,22 @@ interface HeadersPluginOptions {
|
|
|
32
32
|
* @default false
|
|
33
33
|
*/
|
|
34
34
|
shouldAllowNested?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Should allow API headers
|
|
37
|
+
*
|
|
38
|
+
* If set to `true`, headers for `<MarkdownAPI>` title would also be extracted.
|
|
39
|
+
*
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
shouldAllowApi?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Should allow Example headers
|
|
45
|
+
*
|
|
46
|
+
* If set to `true`, headers for `<MarkdownExample>` title would also be extracted.
|
|
47
|
+
*
|
|
48
|
+
* @default true
|
|
49
|
+
*/
|
|
50
|
+
shouldAllowExample?: boolean;
|
|
35
51
|
}
|
|
36
52
|
interface TocItem {
|
|
37
53
|
id: string;
|
|
@@ -50,4 +66,5 @@ declare module '@md-plugins/shared' {
|
|
|
50
66
|
|
|
51
67
|
declare const headersPlugin: PluginWithOptions<HeadersPluginOptions>;
|
|
52
68
|
|
|
53
|
-
export {
|
|
69
|
+
export { headersPlugin };
|
|
70
|
+
export type { HeadersPluginOptions, TocItem };
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,22 @@ interface HeadersPluginOptions {
|
|
|
32
32
|
* @default false
|
|
33
33
|
*/
|
|
34
34
|
shouldAllowNested?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Should allow API headers
|
|
37
|
+
*
|
|
38
|
+
* If set to `true`, headers for `<MarkdownAPI>` title would also be extracted.
|
|
39
|
+
*
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
shouldAllowApi?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Should allow Example headers
|
|
45
|
+
*
|
|
46
|
+
* If set to `true`, headers for `<MarkdownExample>` title would also be extracted.
|
|
47
|
+
*
|
|
48
|
+
* @default true
|
|
49
|
+
*/
|
|
50
|
+
shouldAllowExample?: boolean;
|
|
35
51
|
}
|
|
36
52
|
interface TocItem {
|
|
37
53
|
id: string;
|
|
@@ -50,4 +66,5 @@ declare module '@md-plugins/shared' {
|
|
|
50
66
|
|
|
51
67
|
declare const headersPlugin: PluginWithOptions<HeadersPluginOptions>;
|
|
52
68
|
|
|
53
|
-
export {
|
|
69
|
+
export { headersPlugin };
|
|
70
|
+
export type { HeadersPluginOptions, TocItem };
|
package/dist/index.mjs
CHANGED
|
@@ -1,74 +1,96 @@
|
|
|
1
|
-
|
|
1
|
+
const andRE = /&/g;
|
|
2
|
+
const rCombining = /[\u0300-\u036F]/g;
|
|
3
|
+
const rControl = /[\u0000-\u001f]/g;
|
|
4
|
+
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g;
|
|
5
|
+
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");
|
|
6
|
+
function resolvePluginOptions(options, key, defaults) {
|
|
7
|
+
if (options && typeof options === "object" && key in options) {
|
|
8
|
+
return { ...defaults, ...options[key] };
|
|
9
|
+
}
|
|
10
|
+
return { ...defaults, ...options };
|
|
11
|
+
}
|
|
2
12
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
13
|
+
const DEFAULT_HEADERS_PLUGIN_OPTIONS = {
|
|
14
|
+
level: [2, 3],
|
|
15
|
+
slugify: slugify,
|
|
16
|
+
// Default to an identity function if no formatter is provided.
|
|
17
|
+
format: (str) => str,
|
|
18
|
+
shouldAllowNested: false,
|
|
19
|
+
shouldAllowApi: true,
|
|
20
|
+
shouldAllowExample: true
|
|
21
|
+
};
|
|
22
|
+
function parseContent(str, slugify, format) {
|
|
23
|
+
const title = String(str).replace(/<\/?[^>]+(>|$)/g, "").trim();
|
|
10
24
|
return {
|
|
11
|
-
id: slugify
|
|
12
|
-
title: format(title)
|
|
25
|
+
id: slugify(title),
|
|
26
|
+
title: format(title)
|
|
13
27
|
};
|
|
14
28
|
}
|
|
15
|
-
const headersPlugin = (md, {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
const headersPlugin = (md, options) => {
|
|
30
|
+
const {
|
|
31
|
+
level = DEFAULT_HEADERS_PLUGIN_OPTIONS.level,
|
|
32
|
+
slugify = DEFAULT_HEADERS_PLUGIN_OPTIONS.slugify,
|
|
33
|
+
format = DEFAULT_HEADERS_PLUGIN_OPTIONS.format,
|
|
34
|
+
shouldAllowApi = DEFAULT_HEADERS_PLUGIN_OPTIONS.shouldAllowApi,
|
|
35
|
+
shouldAllowExample = DEFAULT_HEADERS_PLUGIN_OPTIONS.shouldAllowExample
|
|
36
|
+
} = resolvePluginOptions(
|
|
37
|
+
options,
|
|
38
|
+
"headersPlugin",
|
|
39
|
+
DEFAULT_HEADERS_PLUGIN_OPTIONS
|
|
40
|
+
);
|
|
20
41
|
const originalHeadingOpen = md.renderer.rules.heading_open;
|
|
21
42
|
const originalHtmlBlock = md.renderer.rules.html_block;
|
|
22
|
-
md.renderer.rules.heading_open = (tokens, idx,
|
|
43
|
+
md.renderer.rules.heading_open = (tokens, idx, options2, env, self) => {
|
|
23
44
|
const token = tokens[idx];
|
|
24
45
|
if (!token) {
|
|
25
|
-
return self.renderToken(tokens, idx,
|
|
46
|
+
return self.renderToken(tokens, idx, options2);
|
|
26
47
|
}
|
|
27
48
|
const headerLevel = Number.parseInt(token.tag.slice(1), 10);
|
|
28
49
|
const contentToken = tokens[idx + 1];
|
|
29
50
|
const content = contentToken && contentToken.children ? contentToken.children.reduce((acc, t) => acc + t.content, "") : "";
|
|
30
|
-
const { id, title } = parseContent(content, slugify
|
|
51
|
+
const { id, title } = parseContent(content, slugify, format);
|
|
31
52
|
token.attrSet("id", id);
|
|
32
53
|
token.attrSet("class", `markdown-heading markdown-${token.tag}`);
|
|
33
54
|
token.attrSet("@click", `copyHeading(\`${id}\`)`);
|
|
34
55
|
env.toc = env.toc || [];
|
|
35
|
-
if (level.includes(headerLevel)) {
|
|
36
|
-
if (headerLevel === level[0]) {
|
|
56
|
+
if ((level ?? []).includes(headerLevel)) {
|
|
57
|
+
if (headerLevel === (level ?? [])[0]) {
|
|
37
58
|
env.toc.push({ id, title });
|
|
38
59
|
} else {
|
|
39
60
|
env.toc.push({ id, title, sub: true });
|
|
40
61
|
}
|
|
41
62
|
}
|
|
42
63
|
if (typeof originalHeadingOpen === "function") {
|
|
43
|
-
return originalHeadingOpen(tokens, idx,
|
|
64
|
+
return originalHeadingOpen(tokens, idx, options2, env, self);
|
|
44
65
|
}
|
|
45
|
-
return self.renderToken(tokens, idx,
|
|
66
|
+
return self.renderToken(tokens, idx, options2);
|
|
46
67
|
};
|
|
47
|
-
md.renderer.rules.html_block = (tokens, idx,
|
|
68
|
+
md.renderer.rules.html_block = (tokens, idx, options2, env, self) => {
|
|
48
69
|
const token = tokens[idx];
|
|
49
70
|
if (!token) {
|
|
50
71
|
return "";
|
|
51
72
|
}
|
|
52
73
|
env.toc = env.toc || [];
|
|
53
|
-
if (
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
const title = `${
|
|
57
|
-
|
|
74
|
+
if (shouldAllowApi && /^<MarkdownApi\s/.test(token.content)) {
|
|
75
|
+
const match = /(?:file|name)="([^"]+)"/.exec(token.content);
|
|
76
|
+
if (match !== null) {
|
|
77
|
+
const title = `${match[1]} API`;
|
|
78
|
+
if (slugify) {
|
|
79
|
+
env.toc.push({ id: slugify(title), title, deep: true });
|
|
80
|
+
}
|
|
58
81
|
}
|
|
59
82
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
env.toc.push({ id: slugify$1(title), title, deep: true });
|
|
83
|
+
if (shouldAllowExample && /^<MarkdownExample(?:\s+title="([^"]*)")?\s*/.test(token.content)) {
|
|
84
|
+
const match = token.content.match(/^<MarkdownExample(?:\s+title="([^"]*)")?\s*/);
|
|
85
|
+
if (match !== null) {
|
|
86
|
+
const title = match[1] ?? "Example";
|
|
87
|
+
if (slugify) {
|
|
88
|
+
env.toc.push({ id: slugify("example-" + title), title, deep: true });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
69
91
|
}
|
|
70
92
|
if (typeof originalHtmlBlock === "function") {
|
|
71
|
-
return originalHtmlBlock(tokens, idx,
|
|
93
|
+
return originalHtmlBlock(tokens, idx, options2, env, self);
|
|
72
94
|
}
|
|
73
95
|
return token.content;
|
|
74
96
|
};
|
package/package.json
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@md-plugins/md-plugin-headers",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
4
|
"description": "A markdown-it plugin for handling headers (H1-H6).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown-it",
|
|
7
7
|
"quasarframework",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
8
|
+
"types",
|
|
9
|
+
"vue"
|
|
10
10
|
],
|
|
11
11
|
"homepage": "https://github.com/md-plugins",
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/md-plugins/md-plugins/issues"
|
|
14
14
|
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "hawkeye64 <galbraith64@gmail.com>",
|
|
15
17
|
"repository": {
|
|
16
18
|
"type": "git",
|
|
17
19
|
"url": "git+https://github.com/md-plugins/md-plugins.git"
|
|
18
20
|
},
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
+
"files": [
|
|
22
|
+
"./dist"
|
|
23
|
+
],
|
|
21
24
|
"type": "module",
|
|
25
|
+
"module": "./dist/index.mjs",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
22
27
|
"exports": {
|
|
23
28
|
".": {
|
|
24
29
|
"import": {
|
|
@@ -27,24 +32,17 @@
|
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
34
|
},
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
"files": [
|
|
33
|
-
"./dist"
|
|
34
|
-
],
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"markdown-it": "^14.1.0",
|
|
37
|
-
"@md-plugins/shared": "0.1.0-alpha.9"
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
38
37
|
},
|
|
39
38
|
"devDependencies": {
|
|
40
|
-
"@types/markdown-it": "^14.1.2"
|
|
39
|
+
"@types/markdown-it": "^14.1.2",
|
|
40
|
+
"markdown-it": "^14.1.1",
|
|
41
|
+
"@md-plugins/shared": "0.1.0-beta.0"
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"markdown-it": "^14.1.0"
|
|
44
45
|
},
|
|
45
|
-
"publishConfig": {
|
|
46
|
-
"access": "public"
|
|
47
|
-
},
|
|
48
46
|
"scripts": {
|
|
49
47
|
"build": "unbuild",
|
|
50
48
|
"clean": "rm -rf dist/ node_modules/",
|