Skip to content

Commit 5082b3d

Browse files
Mister-Hopemeteorlxy
andauthoredMay 16, 2024··
fix(markdown): fix query parsing and absolute link fallback in linksPlugin (close #1536) (#1537)
Co-authored-by: meteorlxy <meteor.lxy@foxmail.com>
1 parent 9003521 commit 5082b3d

File tree

5 files changed

+409
-553
lines changed

5 files changed

+409
-553
lines changed
 

‎packages/markdown/src/plugins/linksPlugin/linksPlugin.ts

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isLinkExternal, normalizeRoutePath } from '@vuepress/shared'
1+
import { inferRoutePath, isLinkExternal } from '@vuepress/shared'
22
import type { PluginWithOptions } from 'markdown-it'
33
import type Token from 'markdown-it/lib/token.mjs'
44
import type { MarkdownEnv } from '../../types.js'
@@ -67,7 +67,7 @@ export const linksPlugin: PluginWithOptions<LinksPluginOptions> = (
6767

6868
// if `href` attr exists, `token.attrs` is not `null`
6969
const hrefAttr = token.attrs![hrefIndex]
70-
const hrefLink = hrefAttr[1]
70+
const hrefLink: string = hrefAttr[1]
7171

7272
// get `base` and `filePathRelative` from `env`
7373
const { base = '/', filePathRelative = null } = env
@@ -83,7 +83,7 @@ export const linksPlugin: PluginWithOptions<LinksPluginOptions> = (
8383

8484
// check if a link is an internal link
8585
const internalLinkMatch = hrefLink.match(
86-
/^((?:.*)(?:\/|\.md|\.html))(#.*)?$/,
86+
/^([^#?]*?(?:\/|\.md|\.html))([#?].*)?$/,
8787
)
8888

8989
if (!internalLinkMatch) {
@@ -97,7 +97,7 @@ export const linksPlugin: PluginWithOptions<LinksPluginOptions> = (
9797

9898
// notice that the path and hash are encoded by markdown-it
9999
const rawPath = internalLinkMatch[1]
100-
const rawHash = internalLinkMatch[2] || ''
100+
const rawHashAndQueries = internalLinkMatch[2] || ''
101101

102102
// resolve relative and absolute path
103103
const { relativePath, absolutePath } = resolvePaths(
@@ -114,16 +114,19 @@ export const linksPlugin: PluginWithOptions<LinksPluginOptions> = (
114114
// normalize markdown file path to route path
115115
// we are removing the `base` from absolute path because it should not be
116116
// passed to `<RouteLink>` or `<RouterLink>`
117-
const normalizedPath = normalizeRoutePath(
118-
absolutePath.replace(new RegExp(`^${base}`), '/'),
117+
const normalizedPath = inferRoutePath(
118+
absolutePath
119+
? absolutePath.replace(new RegExp(`^${base}`), '/')
120+
: relativePath,
119121
)
120122
// replace the original href link with the normalized path
121-
hrefAttr[1] = `${normalizedPath}${rawHash}`
123+
hrefAttr[1] = `${normalizedPath}${rawHashAndQueries}`
122124
// set `hasOpenInternalLink` to modify the ending tag
123125
hasOpenInternalLink = true
124126
} else {
125-
const normalizedPath = normalizeRoutePath(absolutePath)
126-
hrefAttr[1] = `${normalizedPath}${rawHash}`
127+
const normalizedPath = inferRoutePath(absolutePath ?? relativePath)
128+
// replace the original href link with the normalized path
129+
hrefAttr[1] = `${normalizedPath}${rawHashAndQueries}`
127130
}
128131

129132
// extract internal links for file / page existence check
@@ -139,7 +142,7 @@ export const linksPlugin: PluginWithOptions<LinksPluginOptions> = (
139142
return self.renderToken(tokens, idx, options)
140143
}
141144

142-
md.renderer.rules.link_close = (tokens, idx, options, env, self) => {
145+
md.renderer.rules.link_close = (tokens, idx, options, _env, self) => {
143146
// convert ending tag of internal link
144147
if (hasOpenInternalLink) {
145148
hasOpenInternalLink = false

‎packages/markdown/src/plugins/linksPlugin/resolvePaths.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ export const resolvePaths = (
99
base: string,
1010
filePathRelative: string | null,
1111
): {
12-
absolutePath: string
12+
absolutePath: string | null
1313
relativePath: string
1414
} => {
15-
let absolutePath: string
15+
let absolutePath: string | null
1616
let relativePath: string
1717

1818
// if raw path is absolute
@@ -48,7 +48,7 @@ export const resolvePaths = (
4848
// remove leading './'
4949
relativePath = rawPath.replace(/^(?:\.\/)?(.*)$/, '$1')
5050
// just take relative link as absolute link
51-
absolutePath = relativePath
51+
absolutePath = null
5252
}
5353
}
5454

‎packages/markdown/src/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export type MarkdownHeader = PageHeader
4848
export interface MarkdownLink {
4949
raw: string
5050
relative: string
51-
absolute: string
51+
absolute: string | null
5252
}
5353

5454
/**

‎packages/markdown/tests/plugins/linksPlugin.spec.ts

+391-539
Large diffs are not rendered by default.

‎packages/shared/src/utils/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export * from './isLinkExternal.js'
77
export * from './isLinkHttp.js'
88
export * from './isLinkWithProtocol.js'
99
export * from './isPlainObject.js'
10+
export * from './inferRoutePath.js'
1011
export * from './normalizeRoutePath.js'
1112
export * from './omit.js'
1213
export * from './removeEndingSlash.js'

0 commit comments

Comments
 (0)
Please sign in to comment.