-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmod.ts
96 lines (84 loc) · 2.19 KB
/
mod.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
import { characters, locales } from "./lib/locale.ts";
export interface SlugOptions {
replacement: string;
remove: RegExp;
lower: boolean;
strict: boolean;
locale:
| "bg"
| "de"
| "es"
| "fr"
| "pt"
| "uk"
| "vi"
| "da"
| "nb"
| "it"
| "nl"
| "sv";
trim: boolean;
extends: Record<string, string>;
}
/**
* Converts a string into a valid slug
* @example
* console.log(slug("some string")); // some-string
* console.log(slug("some string", "_")); // some_string
* console.log(slug("I ♥ UNICODE")); // I-love-UNICODE
* console.log(slug("I ♥ UNICODE"), { lower: true }); // i-love-unicode
* @example
* slug("some ƒÚÑķÝ and ☢ string", {
* replacement: "-",
* remove: undefined,
* lower: true,
* strict: false,
* locale: "vi",
* trim: true,
* extends: { "☢": "nuclear" },
* }); // some-fUNkY-and-nuclear-string
*/
export function slug(
input: string,
options?: string | Partial<SlugOptions>,
): string {
let settings: SlugOptions = {
replacement: "-",
remove: /[^\w\s$*_+~.()'"!\-:@]+/g,
lower: true,
strict: false,
locale: "vi",
trim: true,
extends: {},
};
if (typeof options === "string") {
settings.replacement = options;
} else {
settings = { ...settings, ...options };
}
// create output string (to modify)
let output = input.normalize();
// trim leading and trailing whitespace
if (settings.trim) output = output.trim();
// remove non-ascii characters
if (settings.strict) output = output.replace(/[^A-Za-z0-9\s]/g, "");
// deal with locales
const finalMap = {
...characters,
...locales[settings.locale],
...settings.extends,
};
for (let i = 0; i < output.length; i++) {
const c = output[i] as keyof typeof finalMap;
if (finalMap[c]) {
output = output.substring(0, i) + finalMap[c] + output.substring(i + 1);
}
}
// make lowercase
if (settings.lower) output = output.toLowerCase();
// convert spaces to replacement characters (and treat multiple spaces as a single space)
output = output.replace(/\s+/g, settings.replacement);
// add remove functionality
output = output.replaceAll(settings.remove, "");
return output;
}