@mehm8128/rehype-toc 1.3.0 → 1.4.1
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.js +27 -36
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,56 +3,54 @@ import { visit } from "unist-util-visit";
|
|
|
3
3
|
//#region src/index.ts
|
|
4
4
|
const rehypeCollapsibleToc = () => {
|
|
5
5
|
return (tree) => {
|
|
6
|
-
const
|
|
6
|
+
const rootOlElement = {
|
|
7
7
|
type: "element",
|
|
8
8
|
tagName: "ol",
|
|
9
9
|
properties: {},
|
|
10
10
|
children: []
|
|
11
11
|
};
|
|
12
12
|
visit(tree, "element", (node) => {
|
|
13
|
-
visitorCallback(node,
|
|
13
|
+
visitorCallback(node, rootOlElement);
|
|
14
14
|
});
|
|
15
|
-
const detailsElement = createCollapsibleToc(
|
|
15
|
+
const detailsElement = createCollapsibleToc(rootOlElement);
|
|
16
16
|
tree.children.unshift(detailsElement);
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
-
const visitorCallback = (node,
|
|
19
|
+
const visitorCallback = (node, rootOlElement) => {
|
|
20
20
|
if (!/^h[2-6]$/.test(node.tagName)) return;
|
|
21
21
|
const headingLevel = getHeadingLevelFromElement(node);
|
|
22
22
|
const liElement = createListItemElement(node);
|
|
23
|
-
const
|
|
23
|
+
const rootOlElementChildren = assertElementNodeList(rootOlElement.children);
|
|
24
24
|
if (headingLevel === 2) {
|
|
25
|
-
|
|
25
|
+
rootOlElement.children.push(liElement);
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const rootElementHeadingLevel = 2;
|
|
29
|
+
const sameLevelOlElement = searchSameLevelOlElement(rootOlElement, headingLevel, rootElementHeadingLevel);
|
|
30
|
+
if (sameLevelOlElement) {
|
|
31
|
+
sameLevelOlElement.children.push(liElement);
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
|
-
const deepestLiElement = getDeepestLiElement(
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
deepestLiElement.children.push(
|
|
34
|
+
const deepestLiElement = getDeepestLiElement(rootOlElementChildren);
|
|
35
|
+
const newOlElement = createOlElement();
|
|
36
|
+
newOlElement.children.push(liElement);
|
|
37
|
+
deepestLiElement.children.push(newOlElement);
|
|
37
38
|
};
|
|
38
39
|
/**
|
|
39
40
|
* 引数のolに入っている一番新しいliの中で、levelと同じ見出しレベルのli要素を返す
|
|
40
41
|
*/
|
|
41
|
-
const
|
|
42
|
-
const rootLiElement = assertElementNode(
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const childUlElement = assertElementNodeList(rootLiElement.children)[1];
|
|
48
|
-
if (childUlElement === void 0) return;
|
|
49
|
-
return searchSameLevelUlElement(assertElementNodeList(childUlElement.children), level);
|
|
42
|
+
const searchSameLevelOlElement = (rootOlElement, level, rootElementHeadingLevel) => {
|
|
43
|
+
const rootLiElement = assertElementNode(rootOlElement.children[rootOlElement.children.length - 1]);
|
|
44
|
+
if (level === rootElementHeadingLevel) return rootOlElement;
|
|
45
|
+
const childOlElement = assertElementNodeList(rootLiElement.children)[1];
|
|
46
|
+
if (childOlElement === void 0) return;
|
|
47
|
+
return searchSameLevelOlElement(childOlElement, level, rootElementHeadingLevel + 1);
|
|
50
48
|
};
|
|
51
49
|
/**
|
|
52
50
|
* 引数のolに入っている一番新しいliの中で、一番深いli要素を取得する
|
|
53
51
|
*/
|
|
54
|
-
const getDeepestLiElement = (
|
|
55
|
-
const rootLiElement = assertElementNode(
|
|
52
|
+
const getDeepestLiElement = (rootOlElement) => {
|
|
53
|
+
const rootLiElement = assertElementNode(rootOlElement[rootOlElement.length - 1]);
|
|
56
54
|
const olElement = assertElementNodeList(rootLiElement.children)[1];
|
|
57
55
|
if (!olElement) return rootLiElement;
|
|
58
56
|
return getDeepestLiElement(assertElementNodeList(olElement.children));
|
|
@@ -61,11 +59,7 @@ const getHeadingLevelFromElement = (headingElement) => {
|
|
|
61
59
|
const headingLevel = Number(headingElement.tagName.charAt(1));
|
|
62
60
|
return headingLevel;
|
|
63
61
|
};
|
|
64
|
-
const
|
|
65
|
-
const headingLevel = Number(headingElement.value.charAt(1));
|
|
66
|
-
return headingLevel;
|
|
67
|
-
};
|
|
68
|
-
const createUlElement = () => {
|
|
62
|
+
const createOlElement = () => {
|
|
69
63
|
return {
|
|
70
64
|
type: "element",
|
|
71
65
|
tagName: "ol",
|
|
@@ -77,11 +71,12 @@ const createListItemElement = (node) => {
|
|
|
77
71
|
const headingChildren = node.children.flatMap((child) => child.type === "element" ? child.children : []);
|
|
78
72
|
const headingTextElement = headingChildren.find((child) => child.type === "text");
|
|
79
73
|
if (!headingTextElement) throw new Error("見出しにテキストがありません");
|
|
74
|
+
const headingId = node.properties.id;
|
|
80
75
|
const headingText = headingTextElement.value;
|
|
81
76
|
const anchorElement = {
|
|
82
77
|
type: "element",
|
|
83
78
|
tagName: "a",
|
|
84
|
-
properties: { href: `#${
|
|
79
|
+
properties: { href: `#${headingId}` },
|
|
85
80
|
children: [{
|
|
86
81
|
type: "text",
|
|
87
82
|
value: headingText
|
|
@@ -94,7 +89,7 @@ const createListItemElement = (node) => {
|
|
|
94
89
|
children: [anchorElement]
|
|
95
90
|
};
|
|
96
91
|
};
|
|
97
|
-
const createCollapsibleToc = (
|
|
92
|
+
const createCollapsibleToc = (rootOlElement) => {
|
|
98
93
|
const summaryElement = {
|
|
99
94
|
type: "element",
|
|
100
95
|
tagName: "summary",
|
|
@@ -108,7 +103,7 @@ const createCollapsibleToc = (rootUlElement) => {
|
|
|
108
103
|
type: "element",
|
|
109
104
|
tagName: "details",
|
|
110
105
|
properties: {},
|
|
111
|
-
children: [summaryElement,
|
|
106
|
+
children: [summaryElement, rootOlElement]
|
|
112
107
|
};
|
|
113
108
|
return detailsElement;
|
|
114
109
|
};
|
|
@@ -120,10 +115,6 @@ const assertElementNodeList = (nodeList) => {
|
|
|
120
115
|
if (nodeList.some((node) => node.type !== "element")) throw new Error("Elementノードではありません");
|
|
121
116
|
return nodeList;
|
|
122
117
|
};
|
|
123
|
-
const assertElementText = (node) => {
|
|
124
|
-
if (node.type !== "text") throw new Error("Textノードではありません");
|
|
125
|
-
return node;
|
|
126
|
-
};
|
|
127
118
|
|
|
128
119
|
//#endregion
|
|
129
120
|
export { rehypeCollapsibleToc };
|