Skip to content

Commit e594e39

Browse files
committed
Better support for relative links
1 parent 4e8d6df commit e594e39

File tree

3 files changed

+76
-22
lines changed

3 files changed

+76
-22
lines changed

src/core/render/compiler.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ export class Compiler {
231231
origin.code = highlightCodeCompiler({ renderer });
232232
origin.link = linkCompiler({
233233
renderer,
234+
contentBase,
234235
router,
235236
linkTarget,
236237
linkRel,

src/core/render/compiler/link.js

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { getAndRemoveConfig } from '../utils.js';
2-
import { isAbsolutePath } from '../../router/util.js';
2+
import { isAbsolutePath, getPath, getParentPath } from '../../router/util.js';
3+
4+
const GET_EXTENSION_REGEXP = /(?:\.([^.]+))?$/;
5+
const GET_REDUNDANT_DOTS = /\/\.\//g;
36

47
export const linkCompiler = ({
58
renderer,
9+
contentBase,
610
router,
711
linkTarget,
812
linkRel,
@@ -18,29 +22,36 @@ export const linkCompiler = ({
1822
: '';
1923
title = str;
2024

21-
if (
22-
!isAbsolutePath(href) &&
23-
!compilerClass._matchNotCompileLink(href) &&
24-
!config.ignore
25-
) {
26-
if (href === compilerClass.config.homepage) {
27-
href = 'README';
28-
}
25+
if (!config.ignore && !compilerClass._matchNotCompileLink(href)) {
26+
if (!isAbsolutePath(href)) {
27+
if (href === compilerClass.config.homepage) {
28+
href = 'README';
29+
} else {
30+
const ext = GET_EXTENSION_REGEXP.exec(href)[1];
31+
if (!ext || ext === 'md') {
32+
href = router.toURL(href, null, router.getCurrentPath());
33+
} else {
34+
href = getPath(
35+
contentBase,
36+
getParentPath(router.getCurrentPath()),
37+
href
38+
);
39+
}
2940

30-
href = router.toURL(href, null, router.getCurrentPath());
31-
} else {
32-
if (!isAbsolutePath(href) && href.slice(0, 2) === './') {
33-
href =
34-
document.URL.replace(/\/(?!.*\/).*/, '/').replace('#/./', '') + href;
41+
href = href.replace(GET_REDUNDANT_DOTS, '/');
42+
}
43+
} else {
44+
attrs.push(
45+
href.indexOf('mailto:') === 0 ? '' : `target="${linkTarget}"`
46+
);
47+
attrs.push(
48+
href.indexOf('mailto:') === 0
49+
? ''
50+
: linkRel !== ''
51+
? ` rel="${linkRel}"`
52+
: ''
53+
);
3554
}
36-
attrs.push(href.indexOf('mailto:') === 0 ? '' : `target="${linkTarget}"`);
37-
attrs.push(
38-
href.indexOf('mailto:') === 0
39-
? ''
40-
: linkRel !== ''
41-
? ` rel="${linkRel}"`
42-
: ''
43-
);
4455
}
4556

4657
if (config.disabled) {

test/integration/render.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,5 +263,47 @@ describe('render', function () {
263263
`"<p><a href=\\"http://url\\" target=\\"_blank\\" rel=\\"noopener\\" id=\\"someCssID\\">alt text</a></p>"`
264264
);
265265
});
266+
267+
test('relative link with md extension', async function () {
268+
const output = window.marked('[alt text](test.md)');
269+
270+
expect(output).toMatchInlineSnapshot(
271+
`"<p><a href=\\"#/test\\" >alt text</a></p>"`
272+
);
273+
});
274+
275+
test('relative link with md extension starting with "./"', async function () {
276+
const output = window.marked('[alt text](./test.md)');
277+
278+
expect(output).toMatchInlineSnapshot(
279+
`"<p><a href=\\"#/test\\" >alt text</a></p>"`
280+
);
281+
});
282+
283+
test('relative link with extension other than md', async function () {
284+
const output = window.marked('[alt text](test.txt)');
285+
286+
expect(output).toMatchInlineSnapshot(
287+
`"<p><a href=\\"http://127.0.0.1:3001/test.txt\\" >alt text</a></p>"`
288+
);
289+
});
290+
291+
test('relative link with extension other than md starting with "./"', async function () {
292+
const output = window.marked('[alt text](./test.txt)');
293+
294+
expect(output).toMatchInlineSnapshot(
295+
`"<p><a href=\\"http://127.0.0.1:3001/test.txt\\" >alt text</a></p>"`
296+
);
297+
});
298+
299+
test('absolute link with md extension', async function () {
300+
const output = window.marked(
301+
'[alt text](http://www.example.com/test.md)'
302+
);
303+
304+
expect(output).toMatchInlineSnapshot(
305+
`"<p><a href=\\"http://www.example.com/test.md\\" target=\\"_blank\\" rel=\\"noopener\\">alt text</a></p>"`
306+
);
307+
});
266308
});
267309
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy