Skip to content

Commit f045abe

Browse files
authored
fix(MarkdownParser): refine content path in anchor link (#1629)
1 parent a2ac0e1 commit f045abe

File tree

4 files changed

+50
-13
lines changed

4 files changed

+50
-13
lines changed

docs/nuxt.config.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,32 @@ export default defineNuxtConfig({
2222
}
2323
},
2424
content: {
25-
sources: [
26-
{
25+
sources: {
26+
v1: {
2727
name: 'v1',
2828
prefix: '/v1',
2929
driver: 'fs',
3030
base: resolve(__dirname, 'content-v1/en')
3131
},
32-
{
32+
'v1-ja': {
3333
name: 'v1-ja',
3434
prefix: '/ja/v1',
3535
driver: 'fs',
3636
base: resolve(__dirname, 'content-v1/ja')
3737
},
38-
{
38+
'v1-fr': {
3939
name: 'v1-fr',
4040
prefix: '/fr/v1',
4141
driver: 'fs',
4242
base: resolve(__dirname, 'content-v1/fr')
4343
},
44-
{
44+
'v1-ru': {
4545
name: 'v1-ru',
4646
prefix: '/ru/v1',
4747
driver: 'fs',
4848
base: resolve(__dirname, 'content-v1/ru')
4949
}
50-
],
50+
},
5151
highlight: {
5252
preload: ['xml']
5353
}

src/runtime/markdown-parser/handler/link.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { all } from 'mdast-util-to-hast'
55
import { encode } from 'mdurl'
66
import type { MdastNode } from 'mdast-util-to-hast/lib'
77
import { isRelative } from 'ufo'
8+
import { generatePath } from '../../transformers/path-meta'
89

910
type Node = MdastNode & {
1011
title: string
@@ -28,11 +29,8 @@ export default function link (h: H, node: Node) {
2829
}
2930

3031
function normalizeLink (link: string) {
31-
if (isRelative(link) || (!/^https?/.test(link) && !link.startsWith('/'))) {
32-
return link.split('/')
33-
.map(x => x.replace(/^[0-9]*\./g, ''))
34-
.join('/')
35-
.replace(/\.md$/g, '')
32+
if (link.endsWith('.md') && (isRelative(link) || (!/^https?/.test(link) && !link.startsWith('/')))) {
33+
return generatePath(link.replace(/\.md$/, ''), { forceLeadingSlash: false })
3634
} else {
3735
return link
3836
}

src/runtime/transformers/path-meta.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ const isPartial = (path: string): boolean => path.split(/[:/]/).some(part => par
6666
* @param path file full path
6767
* @returns generated slug
6868
*/
69-
const generatePath = (path: string): string =>
70-
withLeadingSlash(withoutTrailingSlash(path.split('/').map(part => slugify(refineUrlPart(part), { lower: true })).join('/')))
69+
export const generatePath = (path: string, { forceLeadingSlash = true } = {}): string => {
70+
path = path.split('/').map(part => slugify(refineUrlPart(part), { lower: true })).join('/')
71+
return forceLeadingSlash ? withLeadingSlash(withoutTrailingSlash(path)) : path
72+
}
7173

7274
/**
7375
* generate title from file path

test/features/parser-markdown.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,42 @@ export const testMarkdownParser = () => {
142142
expect(parsed.body.children[1].tag).toEqual('p')
143143
expect(parsed.body.children[1].children[1].props.class).toEqual('font-bold text-green')
144144
})
145+
146+
test('handle markdown file path as link', async () => {
147+
const parsed = await $fetch('/api/parse', {
148+
method: 'POST',
149+
body: {
150+
id: 'content:index.md',
151+
content: [
152+
'[link1](3.x)',
153+
'[link1](./3.x)',
154+
'[link1](foo)',
155+
'[link1](foo.md)',
156+
'[link1](01.foo.md)',
157+
'[link1](./01.foo.md)',
158+
'[link1](./../01.foo.md)',
159+
'[link1](../01.foo.md)',
160+
'[link1](../../01.foo.md)',
161+
'[link1](../../01.foo#bar.md)',
162+
'[link1](../../01.foo.draft.md)',
163+
'[link1](../../_foo.draft.md)'
164+
].join('\n')
165+
}
166+
})
167+
168+
const nodes = parsed.body.children[0].children
169+
expect(nodes.shift().props.href).toEqual('3.x')
170+
expect(nodes.shift().props.href).toEqual('./3.x')
171+
expect(nodes.shift().props.href).toEqual('foo')
172+
expect(nodes.shift().props.href).toEqual('foo')
173+
expect(nodes.shift().props.href).toEqual('foo')
174+
expect(nodes.shift().props.href).toEqual('./foo')
175+
expect(nodes.shift().props.href).toEqual('./../foo')
176+
expect(nodes.shift().props.href).toEqual('../foo')
177+
expect(nodes.shift().props.href).toEqual('../../foo')
178+
expect(nodes.shift().props.href).toEqual('../../foobar')
179+
expect(nodes.shift().props.href).toEqual('../../foo')
180+
expect(nodes.shift().props.href).toEqual('../../_foo')
181+
})
145182
})
146183
}

0 commit comments

Comments
 (0)