@ -16,7 +16,8 @@ const indexRE = /(^|.*\/)index.md(#?.*)$/i
export const linkPlugin = (
export const linkPlugin = (
md : MarkdownItAsync ,
md : MarkdownItAsync ,
externalAttrs : Record < string , string > ,
externalAttrs : Record < string , string > ,
base : string
base : string ,
slugify : ( str : string ) = > string
) = > {
) = > {
md . renderer . rules . link_open = (
md . renderer . rules . link_open = (
tokens ,
tokens ,
@ -27,9 +28,12 @@ export const linkPlugin = (
) = > {
) = > {
const token = tokens [ idx ]
const token = tokens [ idx ]
const hrefIndex = token . attrIndex ( 'href' )
const hrefIndex = token . attrIndex ( 'href' )
const targetIndex = token . attrIndex ( 'target' )
if (
const downloadIndex = token . attrIndex ( 'download' )
hrefIndex >= 0 &&
if ( hrefIndex >= 0 && targetIndex < 0 && downloadIndex < 0 ) {
token . attrIndex ( 'target' ) < 0 &&
token . attrIndex ( 'download' ) < 0 &&
token . attrGet ( 'class' ) !== 'header-anchor' // header anchors are already normalized
) {
const hrefAttr = token . attrs ! [ hrefIndex ]
const hrefAttr = token . attrs ! [ hrefIndex ]
const url = hrefAttr [ 1 ]
const url = hrefAttr [ 1 ]
if ( isExternal ( url ) ) {
if ( isExternal ( url ) ) {
@ -54,7 +58,7 @@ export const linkPlugin = (
) {
) {
normalizeHref ( hrefAttr , env )
normalizeHref ( hrefAttr , env )
} else if ( url . startsWith ( '#' ) ) {
} else if ( url . startsWith ( '#' ) ) {
hrefAttr [ 1 ] = decodeURI ( hrefAttr[ 1 ] )
hrefAttr [ 1 ] = decodeURI ( normalizeHash( hrefAttr[ 1 ] ) )
}
}
// append base to internal (non-relative) urls
// append base to internal (non-relative) urls
@ -72,7 +76,7 @@ export const linkPlugin = (
const indexMatch = url . match ( indexRE )
const indexMatch = url . match ( indexRE )
if ( indexMatch ) {
if ( indexMatch ) {
const [ , path , hash ] = indexMatch
const [ , path , hash ] = indexMatch
url = path + hash
url = path + normalizeHash( hash)
} else {
} else {
let cleanUrl = url . replace ( /[?#].*$/ , '' )
let cleanUrl = url . replace ( /[?#].*$/ , '' )
// transform foo.md -> foo[.html]
// transform foo.md -> foo[.html]
@ -88,7 +92,7 @@ export const linkPlugin = (
cleanUrl += '.html'
cleanUrl += '.html'
}
}
const parsed = new URL ( url , 'http://a.com' )
const parsed = new URL ( url , 'http://a.com' )
url = cleanUrl + parsed . search + parsed. hash
url = cleanUrl + parsed . search + normalizeHash( parsed. hash )
}
}
// ensure leading . for relative paths
// ensure leading . for relative paths
@ -103,6 +107,10 @@ export const linkPlugin = (
hrefAttr [ 1 ] = decodeURI ( url )
hrefAttr [ 1 ] = decodeURI ( url )
}
}
function normalizeHash ( str : string ) {
return str ? encodeURI ( '#' + slugify ( decodeURI ( str ) . slice ( 1 ) ) ) : ''
}
function pushLink ( link : string , env : MarkdownEnv ) {
function pushLink ( link : string , env : MarkdownEnv ) {
const links = env . links || ( env . links = [ ] )
const links = env . links || ( env . links = [ ] )
links . push ( link )
links . push ( link )