-
-
Notifications
You must be signed in to change notification settings - Fork 75
/
resolve_urls.ts
78 lines (64 loc) 路 1.96 KB
/
resolve_urls.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import { posix } from "../deps/path.ts";
import modifyUrls from "./modify_urls.ts";
import { normalizePath } from "../core/utils/path.ts";
import type Site from "../core/site.ts";
/** A plugin to convert links to source files to the final page */
export default function () {
return (site: Site) => {
const cache = new Map<string, string | null>();
site.addEventListener("beforeUpdate", () => cache.clear());
site.use(modifyUrls({
fn(url, page) {
// It's a pretty url or absolute url, so we don't need to do anything
if (ignore(url)) {
return url;
}
let [file, rest] = getPathInfo(url);
if (!file.startsWith("~")) {
file = posix.resolve(
posix.dirname(normalizePath(page.src.path)),
file,
);
}
if (cache.has(file)) {
const cached = cache.get(file);
return cached ? cached + rest : url;
}
try {
const resolved = file.startsWith("~")
? site.url(file)
: site.url(`~${file}`);
cache.set(file, resolved);
return resolved + rest;
} catch {
cache.set(file, null);
}
return url;
},
}));
};
}
/**
* Split the filename and the extra content (query or hash) from a path
* Example: "/foo.md?hello=world" => ["/foo.md", "?hello=world"]
* Example: "/foo.md#hello=world" => ["/foo.md", "#hello=world"]
*/
export function getPathInfo(path: string): [string, string] {
let file = path, rest = "";
if (path.includes("?")) {
[file, rest] = path.split("?", 2);
rest = `?${rest}`;
} else if (path.includes("#")) {
[file, rest] = path.split("#", 2);
rest = `#${rest}`;
}
return [file, rest];
}
function ignore(url: string) {
return !url ||
url.startsWith("?") ||
url.startsWith("#") ||
url.startsWith("data:") ||
url.includes("//") ||
(url.endsWith("/") && !url.startsWith("~")); // Pretty url
}