Skip to content

Commit

Permalink
feat(markdown): add absolutePathPrependBase option for assets plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
meteorlxy committed Dec 20, 2023
1 parent 1f54a5f commit 634af03
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 24 deletions.
10 changes: 8 additions & 2 deletions e2e/docs/.vuepress/config.ts
Expand Up @@ -6,6 +6,7 @@ import { path } from '@vuepress/utils'
import { e2eTheme } from './theme/node/e2eTheme.js'

const E2E_BASE = (process.env.E2E_BASE ?? '/') as '/' | `/${string}/`
const E2E_BUNDLER = process.env.E2E_BUNDLER ?? 'vite'

export default defineUserConfig({
base: E2E_BASE,
Expand Down Expand Up @@ -42,8 +43,13 @@ export default defineUserConfig({
},
},

bundler:
process.env.E2E_BUNDLER === 'webpack' ? webpackBundler() : viteBundler(),
markdown: {
assets: {
absolutePathPrependBase: E2E_BUNDLER === 'webpack',
},
},

bundler: E2E_BUNDLER === 'webpack' ? webpackBundler() : viteBundler(),

theme: e2eTheme(),
})
47 changes: 28 additions & 19 deletions packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts
Expand Up @@ -4,6 +4,11 @@ import type { MarkdownEnv } from '../../types.js'
import { resolveLink } from './resolveLink.js'

export interface AssetsPluginOptions {
/**
* Whether to prepend base to absolute path
*/
absolutePathPrependBase?: boolean

/**
* Prefix to add to relative assets links
*/
Expand All @@ -15,7 +20,10 @@ export interface AssetsPluginOptions {
*/
export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (
md,
{ relativePathPrefix = '@source' }: AssetsPluginOptions = {},
{
absolutePathPrependBase = false,
relativePathPrefix = '@source',
}: AssetsPluginOptions = {},
) => {
// wrap raw image renderer rule
const rawImageRule = md.renderer.rules.image!
Expand All @@ -27,7 +35,10 @@ export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (

if (link) {
// replace the original link with resolved link
token.attrSet('src', resolveLink(link, relativePathPrefix, env))
token.attrSet(
'src',
resolveLink(link, { env, absolutePathPrependBase, relativePathPrefix }),
)
}

return rawImageRule(tokens, idx, options, env, self)
Expand All @@ -43,12 +54,12 @@ export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (
.replace(
/(<img\b.*?src=)(['"])([^\2]*?)\2/gs,
(_, prefix: string, quote: string, src: string) =>
`${prefix}${quote}${resolveLink(
src.trim(),
relativePathPrefix,
`${prefix}${quote}${resolveLink(src.trim(), {
env,
true,
)}${quote}`,
absolutePathPrependBase,
relativePathPrefix,
strict: true,
})}${quote}`,
)
// handle srcset
.replace(
Expand All @@ -57,18 +68,16 @@ export const assetsPlugin: PluginWithOptions<AssetsPluginOptions> = (
`${prefix}${quote}${srcset
.split(',')
.map((item) =>
item
.trim()
.replace(
/^([^ ]*?)([ \n].*)?$/,
(_, url, descriptor = '') =>
`${resolveLink(
url.trim(),
relativePathPrefix,
env,
true,
)}${descriptor.replace(/[ \n]+/g, ' ').trimEnd()}`,
),
item.trim().replace(
/^([^ ]*?)([ \n].*)?$/,
(_, url, descriptor = '') =>
`${resolveLink(url.trim(), {
env,
absolutePathPrependBase,
relativePathPrefix,
strict: true,
})}${descriptor.replace(/[ \n]+/g, ' ').trimEnd()}`,
),
)
.join(', ')}${quote}`,
)
Expand Down
21 changes: 18 additions & 3 deletions packages/markdown/src/plugins/assetsPlugin/resolveLink.ts
Expand Up @@ -2,11 +2,21 @@ import { path } from '@vuepress/utils'
import { decode } from 'mdurl'
import type { MarkdownEnv } from '../../types.js'

interface ResolveLinkOptions {
env: MarkdownEnv
absolutePathPrependBase?: boolean
relativePathPrefix: string
strict?: boolean
}

export const resolveLink = (
link: string,
relativePathPrefix: string,
env: MarkdownEnv,
strict = false,
{
env,
absolutePathPrependBase = false,
relativePathPrefix,
strict = false,
}: ResolveLinkOptions,
): string => {
// do not resolve data uri
if (link.startsWith('data:')) return link
Expand All @@ -30,5 +40,10 @@ export const resolveLink = (
)}`
}

// prepend base to absolute path if needed
if (absolutePathPrependBase && env.base && link.startsWith('/')) {
resolvedLink = path.join(env.base, resolvedLink)
}

return resolvedLink
}
43 changes: 43 additions & 0 deletions packages/markdown/tests/plugins/assetsPlugin.spec.ts
Expand Up @@ -48,6 +48,7 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => {
description: 'should handle assets link with default options',
md: MarkdownIt().use(assetsPlugin),
env: {
base: '/base/',
filePathRelative: 'sub/foo.md',
},
expected: [
Expand Down Expand Up @@ -83,6 +84,48 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => {
'<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wr4H/wAAAABJRU5ErkJggg==" alt="data-uri">',
],
},
{
description: 'should respect `absolutePathPrependBase` option',
md: MarkdownIt().use(assetsPlugin, {
absolutePathPrependBase: true,
}),
env: {
base: '/base/',
filePathRelative: 'sub/foo.md',
},
expected: [
// relative paths
'<img src="@source/sub/foo.png" alt="foo">',
'<img src="@source/sub/foo.png" alt="foo2">',
'<img src="@source/sub/foo/bar.png" alt="foo-bar">',
'<img src="@source/sub/foo/bar.png" alt="foo-bar2">',
'<img src="@source/baz.png" alt="baz">',
'<img src="@source/../out.png" alt="out">',
'<img src="@source/sub/汉字.png" alt="汉字">',
'<img src="@source/sub/100%.png" alt="100%">',
// absolute paths
'<img src="/base/absolute.png" alt="absolute">',
'<img src="/base/foo/absolute.png" alt="absolute-foo">',
// no-prefix paths
'<img src="@source/sub/no-prefix.png" alt="no-prefix">',
'<img src="@source/sub/foo/no-prefix.png" alt="no-prefix-foo">',
'<img src="@source/sub/@alias/foo.png" alt="alias">',
'<img src="@source/sub/@alias/汉字.png" alt="汉字">',
'<img src="@source/sub/@alias/100%.png" alt="100%">',
'<img src="@source/sub/~@alias/foo.png" alt="~alias">',
'<img src="@source/sub/~@alias/汉字.png" alt="~汉字">',
'<img src="@source/sub/~@alias/100%.png" alt="~100%">',
// keep as is
'<img src="http://foobar.com/icon.png" alt="url">',
'<img src="" alt="empty">',
// invalid paths
'<img src="@source/sub/.../invalid.png" alt="invalid">',
'<img src="@source/sub/.../汉字.png" alt="汉字">',
'<img src="@source/sub/.../100%.png" alt="100%">',
// data uri
'<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wr4H/wAAAABJRU5ErkJggg==" alt="data-uri">',
],
},
{
description: 'should respect `relativePathPrefix` option',
md: MarkdownIt().use(assetsPlugin, {
Expand Down

0 comments on commit 634af03

Please sign in to comment.