remark-flexible-toc 1.2.4 → 1.2.6
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/LICENSE +1 -1
- package/README.md +25 -7
- package/dist/{esm/index.d.ts → index.d.ts} +6 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/{esm/index.js → index.js} +5 -4
- package/dist/index.js.map +1 -0
- package/package.json +29 -25
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/tsconfig.tsbuildinfo +0 -1
- package/src/index.ts +0 -194
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
# remark-flexible-toc
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
**A robust Next.js newsletter `Next.js Weekly` is sponsoring me** 💖
|
|
4
|
+
[](https://nextjsweekly.com/)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
Thank you for supporting open source! 🙌
|
|
6
|
+
A warm thanks 🙌 to [@ErfanEbrahimnia](https://github.com/ErfanEbrahimnia), [@recepkyk](https://github.com/recepkyk), and [@LSeaburg](https://github.com/LSeaburg) for the [support](https://github.com/sponsors/ipikuka) 💖
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
---
|
|
10
9
|
|
|
11
10
|
[![npm version][badge-npm-version]][url-npm-package]
|
|
12
11
|
[![npm downloads][badge-npm-download]][url-npm-package]
|
|
@@ -292,7 +291,7 @@ type TocItem = {
|
|
|
292
291
|
```
|
|
293
292
|
|
|
294
293
|
> [!NOTE]
|
|
295
|
-
> If there is a remark plugin before **`remark-flexible-toc`** in the plugin chain
|
|
294
|
+
> If there is a remark plugin before **`remark-flexible-toc`** in the plugin chain like **`remark-heading-id`** or **`remark-custom-header-id`**, which provides custom id for headings, that custom id takes precedence for `href`.
|
|
296
295
|
|
|
297
296
|
**`remark-flexible-toc`** uses **`github-slugger`** internally for producing unique links. Then, it is possible you to use [**rehype-slug**][rehype-slug] (forIDs on headings) and [**rehype-autolink-headings**][rehype-autolink-headings] (for anchors that link-to-self) because they use the same **`github-slugger`**.
|
|
298
297
|
|
|
@@ -396,6 +395,14 @@ Use of **`remark-flexible-toc`** does not involve rehype (hast) or user content
|
|
|
396
395
|
|
|
397
396
|
I like to contribute the Unified / Remark / MDX ecosystem, so I recommend you to have a look my plugins.
|
|
398
397
|
|
|
398
|
+
### Support My Work ([become a sponsor](https://github.com/sponsors/ipikuka) 🚀)
|
|
399
|
+
|
|
400
|
+
If you find **`remark-flexible-toc`** or any of my projects is useful and helpful, please consider supporting my work. Your sponsorship means a lot to me and keeps these projects alive and updated! 💖
|
|
401
|
+
|
|
402
|
+
My sponsors are going to be featured at the very top of the page and proudly displayed on my [Sponsor Wall](https://github.com/sponsors/ipikuka).
|
|
403
|
+
|
|
404
|
+
Thank you for supporting open source! 🙌
|
|
405
|
+
|
|
399
406
|
### My Remark Plugins
|
|
400
407
|
|
|
401
408
|
- [`remark-flexible-code-titles`](https://www.npmjs.com/package/remark-flexible-code-titles)
|
|
@@ -412,6 +419,8 @@ I like to contribute the Unified / Remark / MDX ecosystem, so I recommend you to
|
|
|
412
419
|
– Remark plugin to expose the table of contents via `vfile.data` or via an option reference
|
|
413
420
|
- [`remark-mdx-remove-esm`](https://www.npmjs.com/package/remark-mdx-remove-esm)
|
|
414
421
|
– Remark plugin to remove import and/or export statements (mdxjsEsm)
|
|
422
|
+
- [`remark-mdx-remove-expressions`](https://www.npmjs.com/package/remark-mdx-remove-expressions)
|
|
423
|
+
– Remark plugin to remove MDX expressions within curlybraces {} in MDX content
|
|
415
424
|
|
|
416
425
|
### My Rehype Plugins
|
|
417
426
|
|
|
@@ -441,6 +450,15 @@ I like to contribute the Unified / Remark / MDX ecosystem, so I recommend you to
|
|
|
441
450
|
- [`recma-mdx-interpolate`](https://www.npmjs.com/package/recma-mdx-interpolate)
|
|
442
451
|
– Recma plugin to enable interpolation of identifiers wrapped in curly braces within the `alt`, `src`, `href`, and `title` attributes of markdown link and image syntax in MDX.
|
|
443
452
|
|
|
453
|
+
### My Unist Utils and Unified Plugins
|
|
454
|
+
|
|
455
|
+
I also build low-level utilities and plugins for the Unified ecosystem that can be used across Remark, Rehype, Recma, and other unist-based abstract syntax trees (ASTs).
|
|
456
|
+
|
|
457
|
+
- [`unist-util-find-between`](https://www.npmjs.com/package/unist-util-find-between)
|
|
458
|
+
– Unist utility to find the nodes between two nodes.
|
|
459
|
+
- [`unified-log-tree`](https://www.npmjs.com/package/unified-log-tree)
|
|
460
|
+
– Unified plugin to log abstract syntax trees (ASTs) for debugging without mutating.
|
|
461
|
+
|
|
444
462
|
## License
|
|
445
463
|
|
|
446
464
|
[MIT License](./LICENSE) © ipikuka
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Plugin } from "unified";
|
|
2
|
+
import type { Root } from "mdast";
|
|
3
3
|
export type Prettify<T> = {
|
|
4
4
|
[K in keyof T]: T[K];
|
|
5
5
|
} & {};
|
|
@@ -12,7 +12,9 @@ export type TocItem = {
|
|
|
12
12
|
depth: HeadingDepth;
|
|
13
13
|
numbering: number[];
|
|
14
14
|
parent: HeadingParent;
|
|
15
|
-
data?:
|
|
15
|
+
data?: {
|
|
16
|
+
[PropertyName: string]: string | number | boolean | (string | number)[] | null | undefined;
|
|
17
|
+
};
|
|
16
18
|
};
|
|
17
19
|
/**
|
|
18
20
|
* tocName (default: "toc") - the key name which is attached into vfile.data
|
|
@@ -36,3 +38,4 @@ export type FlexibleTocOptions = {
|
|
|
36
38
|
};
|
|
37
39
|
declare const RemarkFlexibleToc: Plugin<[FlexibleTocOptions?], Root>;
|
|
38
40
|
export default RemarkFlexibleToc;
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAKlC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,EAAE,CAAC;AAExD,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAExF,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,YAAY,GACZ,oBAAoB,GACpB,UAAU,GACV,WAAW,GACX,mBAAmB,CAAC;AAExB,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjD,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE;QACL,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;KAC5F,CAAC;CACH,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,SAAS,CAAC;CAC1C,CAAC;AA4DF,QAAA,MAAM,iBAAiB,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAmF1D,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -21,7 +21,7 @@ function addNumbering(arr) {
|
|
|
21
21
|
for (let i = 0; i < arr.length; i++) {
|
|
22
22
|
const tocItem = arr[i];
|
|
23
23
|
const depth = tocItem.depth;
|
|
24
|
-
let numbering
|
|
24
|
+
let numbering;
|
|
25
25
|
const prevObj = i > 0 ? arr[i - 1] : undefined;
|
|
26
26
|
const prevDepth = prevObj ? prevObj.depth : undefined;
|
|
27
27
|
const prevNumbering = prevObj ? prevObj.numbering : undefined;
|
|
@@ -78,9 +78,10 @@ const RemarkFlexibleToc = (options) => {
|
|
|
78
78
|
return CONTINUE;
|
|
79
79
|
// Other remark plugins can store custom data in node.data.hProperties
|
|
80
80
|
// I omitted node.data.hName and node.data.hChildren since not related with toc
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
82
|
+
// @ts-ignore, vscode resolves the type but tsc build raises an error awkwardly, saying "hProperties" does not exist in "HeadingData".
|
|
83
|
+
const hProperties = _node.data?.hProperties;
|
|
84
|
+
const data = hProperties ? { ...hProperties } : undefined;
|
|
84
85
|
if (data?.["id"])
|
|
85
86
|
href = `#${data["id"]}`;
|
|
86
87
|
tocItems.push({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Plugin } from \"unified\";\nimport type { Root } from \"mdast\";\nimport { visit, CONTINUE } from \"unist-util-visit\";\nimport GithubSlugger from \"github-slugger\";\nimport { toString } from \"mdast-util-to-string\";\n\nexport type Prettify<T> = { [K in keyof T]: T[K] } & {};\n\nexport type PartiallyRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;\n\nexport type HeadingParent =\n | \"root\"\n | \"blockquote\"\n | \"footnoteDefinition\"\n | \"listItem\"\n | \"container\"\n | \"mdxJsxFlowElement\";\n\nexport type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport type TocItem = {\n value: string;\n href: string;\n depth: HeadingDepth;\n numbering: number[];\n parent: HeadingParent;\n data?: {\n [PropertyName: string]: string | number | boolean | (string | number)[] | null | undefined;\n };\n};\n\n/**\n * tocName (default: \"toc\") - the key name which is attached into vfile.data\n * tocRef (default: []) — another way of exposing the tocItems\n * maxDepth (default: 6) — max heading depth to include in the table of contents; this is inclusive: when set to 3, level three headings are included\n * skipLevels (default: [1]) — disallowed heading levels, by default the article h1 is not expected to be in the TOC\n * skipParents (default: []) — disallow headings to be children of certain node types, (the \"root\" can not be skipped)\n * exclude — headings to skip, wrapped in new RegExp('^(' + value + ')$', 'i'); any heading matching this expression will not be present in the table of contents\n * prefix - the text that will be attached to headings as prefix, like \"text-prefix-\"\n * callback - It is a callback function to take the array of toc items as an argument\n */\nexport type FlexibleTocOptions = {\n tocName?: string;\n tocRef?: TocItem[];\n maxDepth?: HeadingDepth;\n skipLevels?: HeadingDepth[];\n skipParents?: Exclude<HeadingParent, \"root\">[];\n exclude?: string | string[];\n prefix?: string;\n callback?: (toc: TocItem[]) => undefined;\n};\n\ntype PartiallyRequiredFlexibleTocOptions = Prettify<\n PartiallyRequired<\n FlexibleTocOptions,\n \"tocName\" | \"tocRef\" | \"maxDepth\" | \"skipLevels\" | \"skipParents\"\n >\n>;\n\nconst DEFAULT_SETTINGS: FlexibleTocOptions = {\n tocName: \"toc\",\n tocRef: [],\n maxDepth: 6,\n skipLevels: [1],\n skipParents: [],\n};\n\n/**\n * adds numberings to the TOC items.\n * why \"number[]\"? It is because up to you joining with dot or dash or slicing the first number (reserved for h1)\n *\n * [1]\n * [1,1]\n * [1,2]\n * [1,2,1]\n */\nfunction addNumbering(arr: TocItem[]) {\n for (let i = 0; i < arr.length; i++) {\n const tocItem = arr[i];\n const depth = tocItem.depth;\n\n let numbering: number[];\n\n const prevObj = i > 0 ? arr[i - 1] : undefined;\n const prevDepth = prevObj ? prevObj.depth : undefined;\n const prevNumbering = prevObj ? prevObj.numbering : undefined;\n\n if (!prevNumbering || !prevDepth) {\n numbering = Array.from({ length: depth }, () => 1);\n } else if (depth === prevDepth) {\n numbering = [...prevNumbering];\n numbering[depth - 1]++;\n } else if (depth > prevDepth) {\n numbering = [\n ...prevNumbering,\n ...(Array.from(\n { length: depth - prevDepth }, // if depth is more bigger than prevDepth, put more \"1\" inside the array\n () => 1,\n ) as HeadingDepth[]),\n ];\n } else {\n // if (depth < prevDepth)\n numbering = prevNumbering.slice(0, depth);\n numbering[depth - 1]++;\n }\n\n tocItem.numbering = numbering;\n }\n}\n\nconst RemarkFlexibleToc: Plugin<[FlexibleTocOptions?], Root> = (options) => {\n const settings = Object.assign(\n {},\n DEFAULT_SETTINGS,\n options,\n ) as PartiallyRequiredFlexibleTocOptions;\n\n const exludeRegexFilter =\n settings.exclude &&\n (Array.isArray(settings.exclude)\n ? new RegExp(\"^(\" + settings.exclude.join(\"|\") + \")$\", \"i\")\n : new RegExp(\"^(\" + settings.exclude + \")$\", \"i\"));\n\n return (tree, file) => {\n const slugger = new GithubSlugger();\n const tocItems: TocItem[] = [];\n\n visit(tree, \"heading\", (_node, _index, _parent) => {\n /* v8 ignore next -- @preserve */\n if (!_parent || typeof _index === \"undefined\") return;\n\n const depth = _node.depth;\n const value = toString(_node, { includeImageAlt: false });\n let href = `#${settings.prefix ?? \"\"}${slugger.slug(value)}`;\n const parent = _parent.type;\n\n // maxDepth check\n if (depth > settings.maxDepth) return CONTINUE;\n\n // skipLevels check\n if (settings.skipLevels.includes(depth)) return CONTINUE;\n\n // skipParents check\n if (parent !== \"root\" && settings.skipParents.includes(parent)) return CONTINUE;\n\n // exclude check\n if (exludeRegexFilter && exludeRegexFilter.test(value)) return CONTINUE;\n\n // Other remark plugins can store custom data in node.data.hProperties\n // I omitted node.data.hName and node.data.hChildren since not related with toc\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore, vscode resolves the type but tsc build raises an error awkwardly, saying \"hProperties\" does not exist in \"HeadingData\".\n const hProperties = _node.data?.hProperties;\n const data = hProperties ? { ...hProperties } : undefined;\n\n if (data?.[\"id\"]) href = `#${data[\"id\"]}`;\n\n tocItems.push({\n value,\n href,\n depth,\n numbering: [],\n parent,\n ...(data && { data }),\n });\n\n return CONTINUE;\n });\n\n addNumbering(tocItems);\n\n // it is allowed to modify the TOC in the callback\n settings.callback?.(tocItems);\n\n // method - 1 for exposing the data via vfile.data **************************\n\n // other plugins are not allowed to mutate the exposed TOC\n // The spreading is slower than push but need to fresh copy\n file.data[settings.tocName] = [...tocItems];\n\n // method - 2 for exposing the data via reference array *********************\n\n if (options?.tocRef) {\n // prevent dublication if the plugin is called more than once\n settings.tocRef.length = 0;\n\n tocItems.forEach((tocItem) => {\n // the tocRef is not allowed to mutate the vfile.data.toc\n settings.tocRef.push(tocItem);\n });\n }\n };\n};\n\nexport default RemarkFlexibleToc;\n"]}
|
package/package.json
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remark-flexible-toc",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "Remark plugin to expose the table of contents via Vfile.data or via an option reference",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
9
15
|
"scripts": {
|
|
10
|
-
"build": "rimraf dist && tsc --build && type-coverage",
|
|
16
|
+
"build": "rimraf dist && tsc --build tsconfig.build.json && type-coverage",
|
|
11
17
|
"format": "npm run prettier && npm run lint",
|
|
12
18
|
"prettier": "prettier --write .",
|
|
13
19
|
"lint": "eslint .",
|
|
14
|
-
"test": "vitest
|
|
20
|
+
"test": "vitest run",
|
|
15
21
|
"test:watch": "vitest",
|
|
16
|
-
"test:file": "vitest
|
|
22
|
+
"test:file": "vitest test.plugin.spec.ts",
|
|
23
|
+
"test-coverage": "vitest run --coverage",
|
|
17
24
|
"prepack": "npm run build",
|
|
18
|
-
"prepublishOnly": "npm run
|
|
19
|
-
"test-coverage": "vitest run --coverage"
|
|
25
|
+
"prepublishOnly": "npm run format && npm run test-coverage"
|
|
20
26
|
},
|
|
21
27
|
"files": [
|
|
22
28
|
"dist/",
|
|
23
|
-
"src/",
|
|
24
29
|
"LICENSE",
|
|
25
30
|
"README.md"
|
|
26
31
|
],
|
|
@@ -48,35 +53,34 @@
|
|
|
48
53
|
"url": "https://github.com/ipikuka/remark-flexible-toc/issues"
|
|
49
54
|
},
|
|
50
55
|
"devDependencies": {
|
|
51
|
-
"@eslint/js": "^
|
|
52
|
-
"@types/node": "^24.
|
|
53
|
-
"@
|
|
54
|
-
"@vitest/
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"eslint": "^9.39.1",
|
|
56
|
+
"@eslint/js": "^10.0.1",
|
|
57
|
+
"@types/node": "^24.12.4",
|
|
58
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
59
|
+
"@vitest/eslint-plugin": "^1.6.18",
|
|
60
|
+
"dedent": "^1.7.2",
|
|
61
|
+
"eslint": "^10.4.0",
|
|
58
62
|
"eslint-config-prettier": "^10.1.8",
|
|
59
|
-
"eslint-plugin-prettier": "^5.5.
|
|
60
|
-
"globals": "^
|
|
61
|
-
"prettier": "^3.
|
|
63
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
64
|
+
"globals": "^17.6.0",
|
|
65
|
+
"prettier": "^3.8.3",
|
|
62
66
|
"rehype-format": "^5.0.1",
|
|
63
67
|
"rehype-stringify": "^10.0.1",
|
|
68
|
+
"remark-custom-header-id": "^1.0.0",
|
|
64
69
|
"remark-gfm": "^4.0.1",
|
|
65
|
-
"remark-heading-id": "^1.0.1",
|
|
66
70
|
"remark-parse": "^11.0.0",
|
|
67
71
|
"remark-rehype": "^11.1.2",
|
|
68
|
-
"rimraf": "^6.1.
|
|
72
|
+
"rimraf": "^6.1.3",
|
|
69
73
|
"type-coverage": "^2.29.7",
|
|
70
74
|
"typescript": "^5.9.3",
|
|
71
|
-
"typescript-eslint": "^8.
|
|
75
|
+
"typescript-eslint": "^8.60.0",
|
|
72
76
|
"unified": "^11.0.5",
|
|
73
|
-
"vitest": "^4.
|
|
77
|
+
"vitest": "^4.1.7"
|
|
74
78
|
},
|
|
75
79
|
"dependencies": {
|
|
76
80
|
"@types/mdast": "^4.0.4",
|
|
77
81
|
"github-slugger": "^2.0.0",
|
|
78
82
|
"mdast-util-to-string": "^4.0.0",
|
|
79
|
-
"unist-util-visit": "^5.
|
|
83
|
+
"unist-util-visit": "^5.1.0"
|
|
80
84
|
},
|
|
81
85
|
"peerDependencies": {
|
|
82
86
|
"unified": "^11"
|
package/dist/esm/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAqDhD,MAAM,gBAAgB,GAAuB;IAC3C,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,EAAE;IACV,QAAQ,EAAE,CAAC;IACX,UAAU,EAAE,CAAC,CAAC,CAAC;IACf,WAAW,EAAE,EAAE;CAChB,CAAC;AAIF;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,GAAc;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5B,IAAI,SAAS,GAAa,EAAE,CAAC;QAE7B,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACtD,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAE9D,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,SAAS,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC;YAC/B,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACzB,CAAC;aAAM,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YAC7B,SAAS,GAAG;gBACV,GAAG,aAAa;gBAChB,GAAI,KAAK,CAAC,IAAI,CACZ,EAAE,MAAM,EAAE,KAAK,GAAG,SAAS,EAAE,EAAE,wEAAwE;gBACvG,GAAG,EAAE,CAAC,CAAC,CACW;aACrB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,yBAAyB;YACzB,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC1C,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAChC,CAAC;AACH,CAAC;AAED,MAAM,iBAAiB,GAAwC,CAAC,OAAO,EAAE,EAAE;IACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAC5B,EAAE,EACF,gBAAgB,EAChB,OAAO,CAC+B,CAAC;IAEzC,MAAM,iBAAiB,GACrB,QAAQ,CAAC,OAAO;QAChB,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC9B,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC;YAC3D,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,OAAO,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAEvD,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QACpB,MAAM,OAAO,GAAG,IAAI,aAAa,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YAChD,iCAAiC;YACjC,IAAI,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW;gBAAE,OAAO;YAEtD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAC1B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1D,IAAI,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAE5B,iBAAiB;YACjB,IAAI,KAAK,GAAG,QAAQ,CAAC,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAE/C,mBAAmB;YACnB,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,OAAO,QAAQ,CAAC;YAEzD,oBAAoB;YACpB,IAAI,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,OAAO,QAAQ,CAAC;YAEhF,gBAAgB;YAChB,IAAI,iBAAiB,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,QAAQ,CAAC;YAExE,sEAAsE;YACtE,+EAA+E;YAC/E,MAAM,IAAI,GAAI,KAAK,CAAC,IAA4B,EAAE,WAAW;gBAC3D,CAAC,CAAC,EAAE,GAAI,KAAK,CAAC,IAA4B,CAAC,WAAW,EAAE;gBACxD,CAAC,CAAC,SAAS,CAAC;YAEd,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC;gBAAE,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAE1C,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK;gBACL,IAAI;gBACJ,KAAK;gBACL,SAAS,EAAE,EAAE;gBACb,MAAM;gBACN,GAAG,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;aACtB,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,YAAY,CAAC,QAAQ,CAAC,CAAC;QAEvB,kDAAkD;QAClD,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;QAE9B,6EAA6E;QAE7E,0DAA0D;QAC1D,2DAA2D;QAC3D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QAE5C,6EAA6E;QAE7E,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YACpB,6DAA6D;YAC7D,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAE3B,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC3B,yDAAyD;gBACzD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["../../src/index.ts"],"version":"5.9.3"}
|
package/src/index.ts
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import { type Plugin } from "unified";
|
|
2
|
-
import { type Root, type HeadingData } from "mdast";
|
|
3
|
-
import { visit, CONTINUE } from "unist-util-visit";
|
|
4
|
-
import GithubSlugger from "github-slugger";
|
|
5
|
-
import { toString } from "mdast-util-to-string";
|
|
6
|
-
|
|
7
|
-
export type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
8
|
-
|
|
9
|
-
export type PartiallyRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
|
|
10
|
-
|
|
11
|
-
export type HeadingParent =
|
|
12
|
-
| "root"
|
|
13
|
-
| "blockquote"
|
|
14
|
-
| "footnoteDefinition"
|
|
15
|
-
| "listItem"
|
|
16
|
-
| "container"
|
|
17
|
-
| "mdxJsxFlowElement";
|
|
18
|
-
|
|
19
|
-
export type HeadingDepth = 1 | 2 | 3 | 4 | 5 | 6;
|
|
20
|
-
|
|
21
|
-
export type TocItem = {
|
|
22
|
-
value: string;
|
|
23
|
-
href: string;
|
|
24
|
-
depth: HeadingDepth;
|
|
25
|
-
numbering: number[];
|
|
26
|
-
parent: HeadingParent;
|
|
27
|
-
data?: Record<string, unknown>;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* tocName (default: "toc") - the key name which is attached into vfile.data
|
|
32
|
-
* tocRef (default: []) — another way of exposing the tocItems
|
|
33
|
-
* maxDepth (default: 6) — max heading depth to include in the table of contents; this is inclusive: when set to 3, level three headings are included
|
|
34
|
-
* skipLevels (default: [1]) — disallowed heading levels, by default the article h1 is not expected to be in the TOC
|
|
35
|
-
* skipParents (default: []) — disallow headings to be children of certain node types, (the "root" can not be skipped)
|
|
36
|
-
* exclude — headings to skip, wrapped in new RegExp('^(' + value + ')$', 'i'); any heading matching this expression will not be present in the table of contents
|
|
37
|
-
* prefix - the text that will be attached to headings as prefix, like "text-prefix-"
|
|
38
|
-
* callback - It is a callback function to take the array of toc items as an argument
|
|
39
|
-
*/
|
|
40
|
-
export type FlexibleTocOptions = {
|
|
41
|
-
tocName?: string;
|
|
42
|
-
tocRef?: TocItem[];
|
|
43
|
-
maxDepth?: HeadingDepth;
|
|
44
|
-
skipLevels?: HeadingDepth[];
|
|
45
|
-
skipParents?: Exclude<HeadingParent, "root">[];
|
|
46
|
-
exclude?: string | string[];
|
|
47
|
-
prefix?: string;
|
|
48
|
-
callback?: (toc: TocItem[]) => undefined;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
type PartiallyRequiredFlexibleTocOptions = Prettify<
|
|
52
|
-
PartiallyRequired<
|
|
53
|
-
FlexibleTocOptions,
|
|
54
|
-
"tocName" | "tocRef" | "maxDepth" | "skipLevels" | "skipParents"
|
|
55
|
-
>
|
|
56
|
-
>;
|
|
57
|
-
|
|
58
|
-
const DEFAULT_SETTINGS: FlexibleTocOptions = {
|
|
59
|
-
tocName: "toc",
|
|
60
|
-
tocRef: [],
|
|
61
|
-
maxDepth: 6,
|
|
62
|
-
skipLevels: [1],
|
|
63
|
-
skipParents: [],
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
type ExtendedHeadingData = HeadingData & { hProperties: Record<string, unknown> };
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* adds numberings to the TOC items.
|
|
70
|
-
* why "number[]"? It is because up to you joining with dot or dash or slicing the first number (reserved for h1)
|
|
71
|
-
*
|
|
72
|
-
* [1]
|
|
73
|
-
* [1,1]
|
|
74
|
-
* [1,2]
|
|
75
|
-
* [1,2,1]
|
|
76
|
-
*/
|
|
77
|
-
function addNumbering(arr: TocItem[]) {
|
|
78
|
-
for (let i = 0; i < arr.length; i++) {
|
|
79
|
-
const tocItem = arr[i];
|
|
80
|
-
const depth = tocItem.depth;
|
|
81
|
-
|
|
82
|
-
let numbering: number[] = [];
|
|
83
|
-
|
|
84
|
-
const prevObj = i > 0 ? arr[i - 1] : undefined;
|
|
85
|
-
const prevDepth = prevObj ? prevObj.depth : undefined;
|
|
86
|
-
const prevNumbering = prevObj ? prevObj.numbering : undefined;
|
|
87
|
-
|
|
88
|
-
if (!prevNumbering || !prevDepth) {
|
|
89
|
-
numbering = Array.from({ length: depth }, () => 1);
|
|
90
|
-
} else if (depth === prevDepth) {
|
|
91
|
-
numbering = [...prevNumbering];
|
|
92
|
-
numbering[depth - 1]++;
|
|
93
|
-
} else if (depth > prevDepth) {
|
|
94
|
-
numbering = [
|
|
95
|
-
...prevNumbering,
|
|
96
|
-
...(Array.from(
|
|
97
|
-
{ length: depth - prevDepth }, // if depth is more bigger than prevDepth, put more "1" inside the array
|
|
98
|
-
() => 1,
|
|
99
|
-
) as HeadingDepth[]),
|
|
100
|
-
];
|
|
101
|
-
} else {
|
|
102
|
-
// if (depth < prevDepth)
|
|
103
|
-
numbering = prevNumbering.slice(0, depth);
|
|
104
|
-
numbering[depth - 1]++;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
tocItem.numbering = numbering;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const RemarkFlexibleToc: Plugin<[FlexibleTocOptions?], Root> = (options) => {
|
|
112
|
-
const settings = Object.assign(
|
|
113
|
-
{},
|
|
114
|
-
DEFAULT_SETTINGS,
|
|
115
|
-
options,
|
|
116
|
-
) as PartiallyRequiredFlexibleTocOptions;
|
|
117
|
-
|
|
118
|
-
const exludeRegexFilter =
|
|
119
|
-
settings.exclude &&
|
|
120
|
-
(Array.isArray(settings.exclude)
|
|
121
|
-
? new RegExp("^(" + settings.exclude.join("|") + ")$", "i")
|
|
122
|
-
: new RegExp("^(" + settings.exclude + ")$", "i"));
|
|
123
|
-
|
|
124
|
-
return (tree, file) => {
|
|
125
|
-
const slugger = new GithubSlugger();
|
|
126
|
-
const tocItems: TocItem[] = [];
|
|
127
|
-
|
|
128
|
-
visit(tree, "heading", (_node, _index, _parent) => {
|
|
129
|
-
/* v8 ignore next -- @preserve */
|
|
130
|
-
if (!_parent || typeof _index === "undefined") return;
|
|
131
|
-
|
|
132
|
-
const depth = _node.depth;
|
|
133
|
-
const value = toString(_node, { includeImageAlt: false });
|
|
134
|
-
let href = `#${settings.prefix ?? ""}${slugger.slug(value)}`;
|
|
135
|
-
const parent = _parent.type;
|
|
136
|
-
|
|
137
|
-
// maxDepth check
|
|
138
|
-
if (depth > settings.maxDepth) return CONTINUE;
|
|
139
|
-
|
|
140
|
-
// skipLevels check
|
|
141
|
-
if (settings.skipLevels.includes(depth)) return CONTINUE;
|
|
142
|
-
|
|
143
|
-
// skipParents check
|
|
144
|
-
if (parent !== "root" && settings.skipParents.includes(parent)) return CONTINUE;
|
|
145
|
-
|
|
146
|
-
// exclude check
|
|
147
|
-
if (exludeRegexFilter && exludeRegexFilter.test(value)) return CONTINUE;
|
|
148
|
-
|
|
149
|
-
// Other remark plugins can store custom data in node.data.hProperties
|
|
150
|
-
// I omitted node.data.hName and node.data.hChildren since not related with toc
|
|
151
|
-
const data = (_node.data as ExtendedHeadingData)?.hProperties
|
|
152
|
-
? { ...(_node.data as ExtendedHeadingData).hProperties }
|
|
153
|
-
: undefined;
|
|
154
|
-
|
|
155
|
-
if (data?.["id"]) href = `#${data["id"]}`;
|
|
156
|
-
|
|
157
|
-
tocItems.push({
|
|
158
|
-
value,
|
|
159
|
-
href,
|
|
160
|
-
depth,
|
|
161
|
-
numbering: [],
|
|
162
|
-
parent,
|
|
163
|
-
...(data && { data }),
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
return CONTINUE;
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
addNumbering(tocItems);
|
|
170
|
-
|
|
171
|
-
// it is allowed to modify the TOC in the callback
|
|
172
|
-
settings.callback?.(tocItems);
|
|
173
|
-
|
|
174
|
-
// method - 1 for exposing the data via vfile.data **************************
|
|
175
|
-
|
|
176
|
-
// other plugins are not allowed to mutate the exposed TOC
|
|
177
|
-
// The spreading is slower than push but need to fresh copy
|
|
178
|
-
file.data[settings.tocName] = [...tocItems];
|
|
179
|
-
|
|
180
|
-
// method - 2 for exposing the data via reference array *********************
|
|
181
|
-
|
|
182
|
-
if (options?.tocRef) {
|
|
183
|
-
// prevent dublication if the plugin is called more than once
|
|
184
|
-
settings.tocRef.length = 0;
|
|
185
|
-
|
|
186
|
-
tocItems.forEach((tocItem) => {
|
|
187
|
-
// the tocRef is not allowed to mutate the vfile.data.toc
|
|
188
|
-
settings.tocRef.push(tocItem);
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
export default RemarkFlexibleToc;
|