2
2
// a file ending with data.(j|t)s will be evaluated in Node.js
3
3
import fs from 'fs'
4
4
import path from 'path'
5
+ import type { MultiSidebarConfig } from '@vue/theme/src/vitepress/config'
5
6
import { sidebar } from '../../.vitepress/config'
6
7
7
8
interface APIHeader {
@@ -11,6 +12,7 @@ interface APIHeader {
11
12
12
13
export interface APIGroup {
13
14
text : string
15
+ anchor : string
14
16
items : {
15
17
text : string
16
18
link : string
@@ -26,8 +28,9 @@ export default {
26
28
watch : './*.md' ,
27
29
// read from fs and generate the data
28
30
load ( ) : APIGroup [ ] {
29
- return sidebar [ '/api/' ] . map ( ( group ) => ( {
31
+ return ( sidebar as MultiSidebarConfig ) [ '/api/' ] . map ( ( group ) => ( {
30
32
text : group . text ,
33
+ anchor : slugify ( group . text ) ,
31
34
items : group . items . map ( ( item ) => ( {
32
35
...item ,
33
36
headers : parsePageHeaders ( item . link )
@@ -57,22 +60,39 @@ function parsePageHeaders(link: string) {
57
60
const h2s = src . match ( / ^ # # [ ^ \n ] + / gm)
58
61
let headers : APIHeader [ ] = [ ]
59
62
if ( h2s ) {
63
+ const anchorRE = / \{ # ( [ ^ } ] + ) \} /
60
64
headers = h2s . map ( ( h ) => {
61
- const text = h
62
- . slice ( 2 )
63
- . replace ( / < s u p c l a s s = .* / , '' )
64
- . replace ( / \\ < / g, '<' )
65
- . replace ( / ` ( [ ^ ` ] + ) ` / g, '$1' )
66
- . replace ( / \{ # ( [ a - z A - Z 0 - 9 - ] + ) \} / g, '' ) // hidden anchor tag
67
- . trim ( )
68
- const anchor = h . match ( / \{ # ( [ a - z A - Z 0 - 9 - ] + ) \} / ) ?. [ 1 ] ?? text
69
- return { text, anchor }
70
- }
71
- )
65
+ const text = h
66
+ . slice ( 2 )
67
+ . replace ( / < s u p c l a s s = .* / , '' )
68
+ . replace ( / \\ < / g, '<' )
69
+ . replace ( / ` ( [ ^ ` ] + ) ` / g, '$1' )
70
+ . replace ( anchorRE , '' ) // hidden anchor tag
71
+ . trim ( )
72
+ const anchor = h . match ( anchorRE ) ?. [ 1 ] ?? slugify ( text )
73
+ return { text, anchor }
74
+ } )
72
75
}
73
76
headersCache . set ( fullPath , {
74
77
timestamp,
75
78
headers
76
79
} )
77
80
return headers
78
81
}
82
+
83
+ // same as vitepress' slugify logic
84
+ function slugify ( text : string ) : string {
85
+ return (
86
+ text
87
+ // Replace special characters
88
+ . replace ( / [ \s ~ ` ! @ # $ % ^ & * ( ) \- _ + = [ \] { } | \\ ; : " ' < > , . ? / ] + / g, '-' )
89
+ // Remove continuous separators
90
+ . replace ( / \- { 2 , } / g, '-' )
91
+ // Remove prefixing and trailing separators
92
+ . replace ( / ^ \- + | \- + $ / g, '' )
93
+ // ensure it doesn't start with a number (#121)
94
+ . replace ( / ^ ( \d ) / , '_$1' )
95
+ // lowercase
96
+ . toLowerCase ( )
97
+ )
98
+ }
0 commit comments