@@ -16,7 +16,8 @@ const indexRE = /(^|.*\/)index.md(#?.*)$/i
16
16
export const linkPlugin = (
17
17
md : MarkdownItAsync ,
18
18
externalAttrs : Record < string , string > ,
19
- base : string
19
+ base : string ,
20
+ slugify : ( str : string ) => string
20
21
) => {
21
22
md . renderer . rules . link_open = (
22
23
tokens ,
@@ -27,9 +28,12 @@ export const linkPlugin = (
27
28
) => {
28
29
const token = tokens [ idx ]
29
30
const hrefIndex = token . attrIndex ( 'href' )
30
- const targetIndex = token . attrIndex ( 'target' )
31
- const downloadIndex = token . attrIndex ( 'download' )
32
- if ( hrefIndex >= 0 && targetIndex < 0 && downloadIndex < 0 ) {
31
+ if (
32
+ hrefIndex >= 0 &&
33
+ token . attrIndex ( 'target' ) < 0 &&
34
+ token . attrIndex ( 'download' ) < 0 &&
35
+ token . attrGet ( 'class' ) !== 'header-anchor' // header anchors are already normalized
36
+ ) {
33
37
const hrefAttr = token . attrs ! [ hrefIndex ]
34
38
const url = hrefAttr [ 1 ]
35
39
if ( isExternal ( url ) ) {
@@ -54,7 +58,7 @@ export const linkPlugin = (
54
58
) {
55
59
normalizeHref ( hrefAttr , env )
56
60
} else if ( url . startsWith ( '#' ) ) {
57
- hrefAttr [ 1 ] = decodeURI ( hrefAttr [ 1 ] )
61
+ hrefAttr [ 1 ] = decodeURI ( normalizeHash ( hrefAttr [ 1 ] ) )
58
62
}
59
63
60
64
// append base to internal (non-relative) urls
@@ -72,7 +76,7 @@ export const linkPlugin = (
72
76
const indexMatch = url . match ( indexRE )
73
77
if ( indexMatch ) {
74
78
const [ , path , hash ] = indexMatch
75
- url = path + hash
79
+ url = path + normalizeHash ( hash )
76
80
} else {
77
81
let cleanUrl = url . replace ( / [ ? # ] .* $ / , '' )
78
82
// transform foo.md -> foo[.html]
@@ -88,7 +92,7 @@ export const linkPlugin = (
88
92
cleanUrl += '.html'
89
93
}
90
94
const parsed = new URL ( url , 'http://a.com' )
91
- url = cleanUrl + parsed . search + parsed . hash
95
+ url = cleanUrl + parsed . search + normalizeHash ( parsed . hash )
92
96
}
93
97
94
98
// ensure leading . for relative paths
@@ -103,6 +107,10 @@ export const linkPlugin = (
103
107
hrefAttr [ 1 ] = decodeURI ( url )
104
108
}
105
109
110
+ function normalizeHash ( str : string ) {
111
+ return str ? encodeURI ( '#' + slugify ( decodeURI ( str ) . slice ( 1 ) ) ) : ''
112
+ }
113
+
106
114
function pushLink ( link : string , env : MarkdownEnv ) {
107
115
const links = env . links || ( env . links = [ ] )
108
116
links . push ( link )
0 commit comments