Skip to content

Commit 01b72d6

Browse files
author
Matt Copas
committed
Convert relative paths to absolute when checking links
1 parent 115d8d4 commit 01b72d6

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

example/docs/tests/a/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
This file is the index.md in the `a` folder. It appears on the path as with a trailing slash.
44

5-
To link relatively to the folder `b` you should use, [b/](b/) or [b/index](b/index) the last has the advantage that is also works in the raw markdown. A full link is also valid [/tests/a/b/](/tests/a/b/) or [/tests/a/b/index](/tests/a/b/index) linking to headings is also supported [b/#link-test](b/#link-test) and [b/index#link-test](b/index#link-test).
5+
To link relatively to the folder `b` you should use, [b/](b/) or [b/index](b/index) the last has the advantage that is also works in the raw markdown. A full link is also valid [/tests/a/b/](/tests/a/b/) or [/tests/a/b/index](/tests/a/b/index) linking to headings is also supported [b/#link-test](b/#link-test) and [b/index#link-test](b/index#link-test).
6+
7+
You can also link 'up' directories, for example: [../a](../a), [../a/mdTest](../../tests/mdTest), [../../tests/a/b#link-test](../../tests/a/b#link-test)
68

79
We consider paths as case insensitive, so the following also work [B/](B/) or [B/Index](B/Index).
810

911
The following are invalid.
1012

1113
```markdown
12-
[../](../) // not supported
13-
[../a](../a) // not supported
1414
[a/b/c/d](a/b/c/d) // missing
1515
[b/#link-test](b/#link-tests) // missing
1616
```

theme/plugins/check-links/index.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,28 @@ function getCacheKey(node) {
66
return `check-links-${node.id}-${node.internal.contentDigest}`
77
}
88

9+
function getPosition(string, subString, index) {
10+
return string.split(subString, index).join(subString).length;
11+
}
12+
13+
function convertToBasePath(link, path) {
14+
if (link.startsWith('../')) {
15+
// Convert the relative link to an absolute one
16+
const moveUpDirectoryCount = (link.match(/\.\.\//g) || []).length
17+
let pathWithoutTrailingSlash = path[path.length - 1] === '/' ? path.slice(0, path.length - 1) : path
18+
const pathSlashCount = (path.match(/\//g) || []).length
19+
const indexToSliceTo = getPosition(pathWithoutTrailingSlash, '/', pathSlashCount - moveUpDirectoryCount) + 1
20+
const slicedPath = pathWithoutTrailingSlash.slice(0, indexToSliceTo)
21+
const slicedLink = link.slice(moveUpDirectoryCount * 3, link.length)
22+
const concat = slicedPath.concat(slicedLink)
23+
return concat.toLowerCase()
24+
}
25+
return link.toLowerCase().replace(/^\.\//, '') // strip ./
26+
27+
}
28+
929
function getHeadingsMapKey(link, path) {
10-
let basePath = link.toLowerCase().replace(/^\.\//, '') // strip ./
30+
let basePath = convertToBasePath(link, path)
1131
const hashIndex = basePath.indexOf('#')
1232
const hasHash = hashIndex !== -1
1333
const hashId = hasHash ? basePath.slice(hashIndex + 1) : null
@@ -121,7 +141,8 @@ module.exports = async (
121141
return false
122142
}
123143

124-
const headings = headingsMap[key]
144+
// If no heading is found, try again with a trailing /
145+
const headings = headingsMap[key] == null ? headingsMap[`${key}/`] : headingsMap[key]
125146
if (headings) {
126147
if (hasHash) {
127148
return (

0 commit comments

Comments
 (0)