Skip to content

Commit

Permalink
fix(markdown): fix linksPlugin parsing query and wrong absolute link
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Apr 17, 2024
1 parent 5a4700a commit 366c223
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 48 deletions.
21 changes: 12 additions & 9 deletions packages/markdown/src/plugins/linksPlugin/linksPlugin.ts
@@ -1,4 +1,4 @@
import { isLinkExternal, normalizeRoutePath } from '@vuepress/shared'
import { inferRoutePath, isLinkExternal } from '@vuepress/shared'
import type { PluginWithOptions } from 'markdown-it'
import type Token from 'markdown-it/lib/token.mjs'
import type { MarkdownEnv } from '../../types.js'
Expand Down Expand Up @@ -67,7 +67,7 @@ export const linksPlugin: PluginWithOptions<LinksPluginOptions> = (

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

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

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

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

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

// resolve relative and absolute path
const { relativePath, absolutePath } = resolvePaths(
Expand All @@ -114,16 +114,19 @@ export const linksPlugin: PluginWithOptions<LinksPluginOptions> = (
// normalize markdown file path to route path
// we are removing the `base` from absolute path because it should not be
// passed to `<RouteLink>` or `<RouterLink>`
const normalizedPath = normalizeRoutePath(
absolutePath.replace(new RegExp(`^${base}`), '/'),
const normalizedPath = inferRoutePath(
absolutePath
? absolutePath.replace(new RegExp(`^${base}`), '/')
: relativePath,
)
// replace the original href link with the normalized path
hrefAttr[1] = `${normalizedPath}${rawHash}`
hrefAttr[1] = `${normalizedPath}${rawHashAndQueries}`
// set `hasOpenInternalLink` to modify the ending tag
hasOpenInternalLink = true
} else {
const normalizedPath = normalizeRoutePath(absolutePath)
hrefAttr[1] = `${normalizedPath}${rawHash}`
const normalizedPath = inferRoutePath(absolutePath ?? relativePath)
// replace the original href link with the normalized path
hrefAttr[1] = `${normalizedPath}${rawHashAndQueries}`
}

// extract internal links for file / page existence check
Expand Down
4 changes: 2 additions & 2 deletions packages/markdown/src/plugins/linksPlugin/resolvePaths.ts
Expand Up @@ -9,7 +9,7 @@ export const resolvePaths = (
base: string,
filePathRelative: string | null,
): {
absolutePath: string
absolutePath: string | null
relativePath: string
} => {
let absolutePath: string
Expand Down Expand Up @@ -48,7 +48,7 @@ export const resolvePaths = (
// remove leading './'
relativePath = rawPath.replace(/^(?:\.\/)?(.*)$/, '$1')
// just take relative link as absolute link
absolutePath = relativePath
absolutePath = null
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/markdown/src/types.ts
Expand Up @@ -48,7 +48,7 @@ export type MarkdownHeader = PageHeader
export interface MarkdownLink {
raw: string
relative: string
absolute: string
absolute: string | null
}

/**
Expand Down
72 changes: 36 additions & 36 deletions packages/markdown/tests/plugins/linksPlugin.spec.ts
Expand Up @@ -195,92 +195,92 @@ describe('@vuepress/markdown > plugins > linksPlugin', () => {
{
raw: 'foo.md',
relative: 'foo.md',
absolute: 'foo.md',
absolute: null,
},
{
raw: 'foo.md#hash',
relative: 'foo.md',
absolute: 'foo.md',
absolute: null,
},
{
raw: './foo.md',
relative: 'foo.md',
absolute: 'foo.md',
absolute: null,
},
{
raw: '../bar.md',
relative: '../bar.md',
absolute: '../bar.md',
absolute: null,
},
{
raw: '../bar.md#hash',
relative: '../bar.md',
absolute: '../bar.md',
absolute: null,
},
{
raw: './../bar.md',
relative: '../bar.md',
absolute: '../bar.md',
absolute: null,
},
{
raw: 'foo/bar.md',
relative: 'foo/bar.md',
absolute: 'foo/bar.md',
absolute: null,
},
{
raw: 'foo/bar.md#hash',
relative: 'foo/bar.md',
absolute: 'foo/bar.md',
absolute: null,
},
{
raw: '../foo/bar.md',
relative: '../foo/bar.md',
absolute: '../foo/bar.md',
absolute: null,
},
{
raw: '../foo/bar.md#hash',
relative: '../foo/bar.md',
absolute: '../foo/bar.md',
absolute: null,
},
{
raw: 'index.md',
relative: 'index.md',
absolute: 'index.md',
absolute: null,
},
{
raw: 'index.md#hash',
relative: 'index.md',
absolute: 'index.md',
absolute: null,
},
{
raw: './index.md',
relative: 'index.md',
absolute: 'index.md',
absolute: null,
},
{
raw: '../index.md',
relative: '../index.md',
absolute: '../index.md',
absolute: null,
},
{
raw: '../foo/bar/index.md',
relative: '../foo/bar/index.md',
absolute: '../foo/bar/index.md',
absolute: null,
},
{
raw: 'readme.md',
relative: 'readme.md',
absolute: 'readme.md',
absolute: null,
},
{
raw: '../readme.md#hash',
relative: '../readme.md',
absolute: '../readme.md',
absolute: null,
},
{
raw: '../foo/bar/readme.md',
relative: '../foo/bar/readme.md',
absolute: '../foo/bar/readme.md',
absolute: null,
},
])
})
Expand Down Expand Up @@ -320,92 +320,92 @@ describe('@vuepress/markdown > plugins > linksPlugin', () => {
{
raw: 'foo.md',
relative: 'foo.md',
absolute: 'foo.md',
absolute: null,
},
{
raw: 'foo.md#hash',
relative: 'foo.md',
absolute: 'foo.md',
absolute: null,
},
{
raw: './foo.md',
relative: 'foo.md',
absolute: 'foo.md',
absolute: null,
},
{
raw: '../bar.md',
relative: '../bar.md',
absolute: '../bar.md',
absolute: null,
},
{
raw: '../bar.md#hash',
relative: '../bar.md',
absolute: '../bar.md',
absolute: null,
},
{
raw: './../bar.md',
relative: '../bar.md',
absolute: '../bar.md',
absolute: null,
},
{
raw: 'foo/bar.md',
relative: 'foo/bar.md',
absolute: 'foo/bar.md',
absolute: null,
},
{
raw: 'foo/bar.md#hash',
relative: 'foo/bar.md',
absolute: 'foo/bar.md',
absolute: null,
},
{
raw: '../foo/bar.md',
relative: '../foo/bar.md',
absolute: '../foo/bar.md',
absolute: null,
},
{
raw: '../foo/bar.md#hash',
relative: '../foo/bar.md',
absolute: '../foo/bar.md',
absolute: null,
},
{
raw: 'index.md',
relative: 'index.md',
absolute: 'index.md',
absolute: null,
},
{
raw: 'index.md#hash',
relative: 'index.md',
absolute: 'index.md',
absolute: null,
},
{
raw: './index.md',
relative: 'index.md',
absolute: 'index.md',
absolute: null,
},
{
raw: '../index.md',
relative: '../index.md',
absolute: '../index.md',
absolute: null,
},
{
raw: '../foo/bar/index.md',
relative: '../foo/bar/index.md',
absolute: '../foo/bar/index.md',
absolute: null,
},
{
raw: 'readme.md',
relative: 'readme.md',
absolute: 'readme.md',
absolute: null,
},
{
raw: '../readme.md#hash',
relative: '../readme.md',
absolute: '../readme.md',
absolute: null,
},
{
raw: '../foo/bar/readme.md',
relative: '../foo/bar/readme.md',
absolute: '../foo/bar/readme.md',
absolute: null,
},
])
})
Expand Down

0 comments on commit 366c223

Please sign in to comment.