fix: toc slug
the3ash committed
Jul 12, 2025 at 00:16 UTC
0bba6d977c197f316bcdea0c6beb5118106e5b71
1 file changed
+35
-1
src/plugins/remark-toc.mjs
+35
-1
@@ -4,6 +4,7 @@ export default function remarkTOC() {
4
return function (tree, file) {
5
const headings = []
6
let headingIndex = 0
7
+ const usedSlugs = new Set()
8
9
// Extract headings from AST
10
visit(tree, 'heading', (node) => {
@@ -21,7 +22,9 @@ export default function remarkTOC() {
22
const text = extractTextContent(node)
23
if (!text) return
24
24
- const id = `heading-${headingIndex}`
25
+ // Generate unique slug from text
26
+ const slug = generateUniqueSlug(text, usedSlugs)
27
+ const id = slug
28
29
if (!node.data) node.data = {}
30
if (!node.data.hProperties) node.data.hProperties = {}
@@ -53,3 +56,34 @@ function extractTextContent(node) {
56
57
return text.trim()
58
}
59
+
60
+// Generate a slug from text
61
+function generateSlug(text) {
62
+ return (
63
+ text
64
+ .toLowerCase()
65
+ // Keep Chinese characters, English letters, numbers, spaces and hyphens
66
+ .replace(/[^\u4e00-\u9fa5a-z0-9\s-]/g, '')
67
+ // Replace spaces with hyphens
68
+ .replace(/\s+/g, '-')
69
+ // Replace multiple hyphens with single hyphen
70
+ .replace(/-+/g, '-')
71
+ // Remove leading and trailing hyphens
72
+ .replace(/^-|-$/g, '')
73
+ )
74
+}
75
+
76
+// Generate a unique slug from text
77
+function generateUniqueSlug(text, usedSlugs) {
78
+ let slug = generateSlug(text)
79
+ let counter = 1
80
+ let uniqueSlug = slug
81
+
82
+ while (usedSlugs.has(uniqueSlug)) {
83
+ uniqueSlug = `${slug}-${counter}`
84
+ counter++
85
+ }
86
+
87
+ usedSlugs.add(uniqueSlug)
88
+ return uniqueSlug
89
+}