@@ -16,7 +16,8 @@ const indexRE = /(^|.*\/)index.md(#?.*)$/i
1616export const linkPlugin = (
1717 md : MarkdownItAsync ,
1818 externalAttrs : Record < string , string > ,
19- base : string
19+ base : string ,
20+ slugify : ( str : string ) => string
2021) => {
2122 md . renderer . rules . link_open = (
2223 tokens ,
@@ -27,9 +28,12 @@ export const linkPlugin = (
2728 ) => {
2829 const token = tokens [ idx ]
2930 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+ ) {
3337 const hrefAttr = token . attrs ! [ hrefIndex ]
3438 const url = hrefAttr [ 1 ]
3539 if ( isExternal ( url ) ) {
@@ -54,9 +58,7 @@ export const linkPlugin = (
5458 ) {
5559 normalizeHref ( hrefAttr , env )
5660 } else if ( url . startsWith ( '#' ) ) {
57- hrefAttr [ 1 ] = decodeURI ( hrefAttr [ 1 ] )
58- . normalize ( 'NFKD' )
59- . replace ( / [ \u0300 - \u036F ] / g, '' )
61+ hrefAttr [ 1 ] = decodeURI ( normalizeHash ( hrefAttr [ 1 ] ) )
6062 }
6163
6264 // append base to internal (non-relative) urls
@@ -74,7 +76,7 @@ export const linkPlugin = (
7476 const indexMatch = url . match ( indexRE )
7577 if ( indexMatch ) {
7678 const [ , path , hash ] = indexMatch
77- url = path + hash . normalize ( 'NFKD' ) . replace ( / [ \u0300 - \u036F ] / g , '' )
79+ url = path + normalizeHash ( hash )
7880 } else {
7981 let cleanUrl = url . replace ( / [ ? # ] .* $ / , '' )
8082 // transform foo.md -> foo[.html]
@@ -90,10 +92,7 @@ export const linkPlugin = (
9092 cleanUrl += '.html'
9193 }
9294 const parsed = new URL ( url , 'http://a.com' )
93- url =
94- cleanUrl +
95- parsed . search +
96- parsed . hash . normalize ( 'NFKD' ) . replace ( / [ \u0300 - \u036F ] / g, '' )
95+ url = cleanUrl + parsed . search + normalizeHash ( parsed . hash )
9796 }
9897
9998 // ensure leading . for relative paths
@@ -108,6 +107,10 @@ export const linkPlugin = (
108107 hrefAttr [ 1 ] = decodeURI ( url )
109108 }
110109
110+ function normalizeHash ( str : string ) {
111+ return str ? encodeURI ( '#' + slugify ( decodeURI ( str ) . slice ( 1 ) ) ) : ''
112+ }
113+
111114 function pushLink ( link : string , env : MarkdownEnv ) {
112115 const links = env . links || ( env . links = [ ] )
113116 links . push ( link )
0 commit comments