-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod.ts
60 lines (48 loc) · 1.37 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
// Utilities
import lowerCase from "./lower-case.ts";
import specials from "./specials.ts";
const regex = /(?:(?:(\s?(?:^|[.\(\)!?;:"-])\s*)(\w))|(\w))(\w*[’']*\w*)/g;
function convertToRegExp(specials: string[]): [RegExp, string][] {
return specials.map((s) => [new RegExp(`\\b${s}\\b`, "gi"), s]);
}
function parseMatch(match: string) {
const firstCharacter = match[0];
// test first character
if (/\s/.test(firstCharacter)) {
// if whitespace - trim and return
return match.substr(1);
}
if (/[\(\)]/.test(firstCharacter)) {
// if parens - this shouldn't be replaced
return null;
}
return match;
}
type Options = {
special?: string[];
};
export default function (str: string, options: Options = {}) {
str = str.toLowerCase().replace(
regex,
(m, lead = "", forced, lower, rest) => {
const parsedMatch = parseMatch(m);
if (!parsedMatch) {
return m;
}
if (!forced) {
const fullLower = lower + rest;
if (lowerCase.has(fullLower)) {
return parsedMatch;
}
}
return lead + (lower || forced).toUpperCase() + rest;
},
);
const customSpecials = options.special || [];
const replace = [...specials, ...customSpecials];
const replaceRegExp = convertToRegExp(replace);
replaceRegExp.forEach(([pattern, s]) => {
str = str.replace(pattern, s);
});
return str;
}