@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 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
- # With npm:
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 { type HeadersPluginOptions, type TocItem, headersPlugin };
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 { type HeadersPluginOptions, type TocItem, headersPlugin };
69
+ export { headersPlugin };
70
+ export type { HeadersPluginOptions, TocItem };
package/dist/index.mjs CHANGED
@@ -1,74 +1,96 @@
1
- import { slugify } from '@md-plugins/shared';
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 titleRE = /<\/?[^>]+(>|$)/g;
4
- const apiRE = /^<MarkdownApi /;
5
- const apiNameRE = /(?:file|name)="([^"]+)"/;
6
- const installationRE = /^<MarkdownInstallation(?:\s+title="([^"]*)")?\s*/;
7
- const exampleRE = /^<MarkdownExample(?:\s+title="([^"]*)")?\s*/;
8
- function parseContent(str, slugify$1 = slugify, format = (_str) => _str) {
9
- const title = String(str).replace(titleRE, "").trim();
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$1(title),
12
- title: format(title) ?? title
25
+ id: slugify(title),
26
+ title: format(title)
13
27
  };
14
28
  }
15
- const headersPlugin = (md, {
16
- level = [2, 3],
17
- slugify: slugify$1 = slugify,
18
- format
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, options, env, self) => {
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, options);
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$1, format);
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, options, env, self);
64
+ return originalHeadingOpen(tokens, idx, options2, env, self);
44
65
  }
45
- return self.renderToken(tokens, idx, options);
66
+ return self.renderToken(tokens, idx, options2);
46
67
  };
47
- md.renderer.rules.html_block = (tokens, idx, options, env, self) => {
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 (apiRE.test(token.content)) {
54
- const match2 = apiNameRE.exec(token.content);
55
- if (match2 !== null) {
56
- const title = `${match2[1]} API`;
57
- env.toc.push({ id: slugify$1(title), title, deep: true });
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
- let match = token.content.match(installationRE);
61
- if (match !== null) {
62
- const title = match[1] ?? "Installation";
63
- env.toc.push({ id: slugify$1(title), title, deep: true });
64
- }
65
- match = token.content.match(exampleRE);
66
- if (match !== null) {
67
- const title = match[1] ?? "Example";
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, options, env, self);
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-alpha.9",
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
- "vue",
9
- "types"
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
- "license": "MIT",
20
- "author": "hawkeye64 <galbraith64@gmail.com>",
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
- "module": "./dist/index.mjs",
31
- "types": "./dist/index.d.ts",
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/",