-
-
Notifications
You must be signed in to change notification settings - Fork 75
/
slugify_urls.ts
102 lines (81 loc) 路 2.3 KB
/
slugify_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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { posix } from "../deps/path.ts";
import { merge } from "../core/utils.ts";
import type { Helper, Page, Site } from "../core.ts";
export interface Options {
/** The list of extensions this plugin applies to */
extensions: string[];
/** Convert the paths to lower case */
lowercase: boolean;
/** Remove all non-alphanumeric characters */
alphanumeric: boolean;
/** Character used as word separator */
separator: string;
/** Characters to replace */
replace: {
[index: string]: string;
};
}
// Default options
export const defaults: Options = {
extensions: [".html"],
lowercase: true,
alphanumeric: true,
separator: "-",
replace: {
"脨": "D", // eth
"冒": "d",
"膼": "D", // crossed D
"膽": "d",
"酶": "o",
"脽": "ss",
"忙": "ae",
"艙": "oe",
},
};
/** A plugin to slugify all URLs, replacing non-URL-safe characters */
export default function (userOptions?: Partial<Options>) {
const options = merge(defaults, userOptions);
const slugify = createSlugifier(options);
return (site: Site) => {
site.filter("slugify", slugify as Helper);
site.preprocess(options.extensions, slugifyUrls);
};
function slugifyUrls(page: Page) {
const { dest } = page;
const path = slugify(dest.path);
if (path === dest.path) {
return;
}
dest.path = path;
page.data.url =
(dest.ext === ".html" && posix.basename(dest.path) === "index")
? dest.path.slice(0, -5)
: dest.path + dest.ext;
}
}
export function createSlugifier(
options: Options = defaults,
): (string: string) => string {
const { lowercase, alphanumeric, separator, replace } = options;
return function (string) {
if (lowercase) {
string = string.toLowerCase();
}
string = string.replaceAll(/[^a-z\d/.-]/giu, (char) => {
if (char in replace) {
return replace[char];
}
if (alphanumeric) {
char = char.normalize("NFKD").replaceAll(/[\u0300-\u036F]/g, "");
}
char = /[\p{L}\u0300-\u036F]/u.test(char) ? char : "-";
return alphanumeric && /[^\w-]/.test(char) ? "" : char;
});
if (lowercase) {
string = string.toLowerCase();
}
return string
.replaceAll(/(?<=^|[/.])-+(?=[^/.-])|(?<=[^/.-])-+(?=$|[/.])/g, "")
.replaceAll(/-+/g, separator);
};
}