pull/5316/merge
Bjorn Lu 2 days ago committed by GitHub
commit be14caf9f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -53,12 +53,12 @@ describe('node/markdown/plugins/link', () => {
const env: {
cleanUrls: boolean
links?: string[]
linkLines?: number[]
linkMetadatas?: { rawLink: string; line?: number }[]
} = { cleanUrls: false }
await md.renderAsync('Intro\n\n[Missing](./missing.md)\n', env)
expect(env.links).toEqual(['./missing'])
expect(env.linkLines).toEqual([3])
expect(env.links).toEqual(['./missing.html'])
expect(env.linkMetadatas).toEqual([{ rawLink: './missing.md', line: 3 }])
})
})

@ -14,6 +14,38 @@ describe('node/markdownToVue', () => {
}
})
test('records link path as written for dead links', async () => {
root = await mkdtemp(path.join(tmpdir(), 'vitepress-link-path-'))
const file = path.join(root, 'index.md')
const src = [
'[a](./a.md)',
'[b](./b#hash)',
'[c](./中文.md)',
'[d](/d)'
].join('\n\n')
await writeFile(file, src)
const siteConfig = await resolveConfig(root, 'build', 'production')
const render = await createMarkdownToVueRenderFn(
siteConfig.srcDir,
{ cache: false },
'/',
false,
false,
siteConfig
)
const result = await render(src, file)
expect(result.deadLinks).toEqual([
{ url: './a.md', file, line: 1 },
{ url: './b#hash', file, line: 3 },
{ url: './中文.md', file, line: 5 },
{ url: '/d', file, line: 7 }
])
})
test('records source line numbers for dead links', async () => {
root = await mkdtemp(path.join(tmpdir(), 'vitepress-dead-link-'))
@ -34,7 +66,7 @@ describe('node/markdownToVue', () => {
const result = await render(src, file)
expect(result.deadLinks).toContainEqual({
url: './missing',
url: './missing.md',
file,
line: 5
})
@ -61,7 +93,7 @@ describe('node/markdownToVue', () => {
const result = await render(src, file)
expect(result.deadLinks).toContainEqual({
url: './missing',
url: './missing.md',
file,
line: 8
})

@ -47,6 +47,7 @@ export const linkPlugin = (
token.attrGet('class') !== 'header-anchor' // header anchors are already normalized
) {
const hrefAttr = token.attrs![hrefIndex]
const rawUrl = decodeURI(hrefAttr[1])
let [url, frag] = hrefAttr[1].split(':~:', 2)
hrefAttr[1] = url
if (isExternal(url)) {
@ -55,7 +56,7 @@ export const linkPlugin = (
})
// catch localhost links as dead link
if (url.replace(EXTERNAL_URL_RE, '').startsWith('//localhost:')) {
pushLink(url, env, token.meta?.vpLine)
pushLink(url, rawUrl, env, token.meta?.vpLine)
}
hrefAttr[1] = url
} else {
@ -95,6 +96,7 @@ export const linkPlugin = (
line?: number
) {
let url = hrefAttr[1]
const rawUrl = decodeURI(url)
const indexMatch = url.match(indexRE)
if (indexMatch) {
@ -124,7 +126,7 @@ export const linkPlugin = (
}
// export it for existence check
pushLink(url.replace(/\.html$/, ''), env, line)
pushLink(url, rawUrl, env, line)
// markdown-it encodes the uri
hrefAttr[1] = decodeURI(url)
@ -134,12 +136,15 @@ export const linkPlugin = (
return str ? encodeURI('#' + slugify(decodeURI(str).slice(1))) : ''
}
function pushLink(link: string, env: MarkdownEnv, line?: number) {
const links = env.links || (env.links = [])
links.push(link)
if (line != null) {
const linkLines = env.linkLines || (env.linkLines = [])
linkLines[links.length - 1] = line
}
function pushLink(
link: string,
rawLink: string,
env: MarkdownEnv,
line?: number
) {
env.links ??= []
env.links.push(link)
env.linkMetadatas ??= []
env.linkMetadatas.push({ rawLink, line })
}
}

@ -174,8 +174,8 @@ export async function createMarkdownToVueRenderFn(
frontmatter = {},
headers = [],
includes = [],
linkLines = [],
links = [],
linkMetadatas = [],
sfcBlocks,
title = ''
} = env
@ -215,10 +215,9 @@ export async function createMarkdownToVueRenderFn(
const dir = path.dirname(file)
for (const [index, rawUrl] of links.entries()) {
let url = rawUrl
const metadata = linkMetadatas[index]
const line =
linkLines[index] == null
? undefined
: linkLines[index] + contentLineOffset
metadata?.line != null ? metadata.line + contentLineOffset : undefined
const { pathname } = new URL(url, 'http://a.com')
if (!treatAsHtml(pathname)) continue
@ -250,7 +249,7 @@ export async function createMarkdownToVueRenderFn(
) &&
!shouldIgnoreDeadLink(url)
) {
recordDeadLink(url, line)
recordDeadLink(metadata.rawLink, line)
}
}
}

6
types/shared.d.ts vendored

@ -591,9 +591,11 @@ export interface MarkdownEnv {
*/
links?: string[]
/**
* The line numbers at which each of `links` appears in the source.
* The metadata of the links collected from the page.
* - `rawLink`: The url as written
* - `line`: The line number at which the link appears in the source.
*/
linkLines?: number[]
linkMetadatas?: { rawLink: string; line?: number }[]
/**
* The absolute paths of the files inlined via `<!--@include-->` and
* imported via `<<<` code snippets, used for watch invalidation.

Loading…
Cancel
Save