-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathtitle.ts
More file actions
151 lines (147 loc) · 4.22 KB
/
title.ts
File metadata and controls
151 lines (147 loc) · 4.22 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// deno-lint-ignore-file no-irregular-whitespace
/**
* Convert a string to titleLc format
*
* Primarily used for comparing links for equality
*
* @example Converts spaces (` `) to underscores (`_`)
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(toTitleLc("sample text"), "sample_text");
* assertEquals(
* toTitleLc("空白入り タイトル"),
* "空白入り_タイトル",
* );
* assertEquals(
* toTitleLc(" 前後にも 空白入り _タイトル "),
* "_前後にも_空白入り__タイトル_",
* );
* ```
*
* @example Converts uppercase to lowercase
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(toTitleLc("Scrapbox-Gyazo"), "scrapbox-gyazo");
* assertEquals(
* toTitleLc("全角アルファベット「Scrapbox」も変換できる"),
* "全角アルファベット「scrapbox」も変換できる",
* );
* assertEquals(
* toTitleLc("Scrapbox is one of the products powered by Nota inc."),
* "scrapbox_is_one_of_the_products_powered_by_nota_inc.",
* );
* ```
*
* @param text - String to convert
* @returns A {@linkcode string} containing the converted text in titleLc format
*/
export const toTitleLc = (text: string): string =>
text.replaceAll(" ", "_").toLowerCase();
/** Convert underscores (`_`) to single-byte spaces (` `)
*
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(revertTitleLc("sample_text"), "sample text");
* assertEquals(
* revertTitleLc("Title_with underscore"),
* "Title with underscore",
* );
* ```
*
* @param text - String to convert
* @returns A {@linkcode string} with underscores converted to spaces
*/
export const revertTitleLc = (text: string): string =>
text.replaceAll("_", " ");
/** Encode a title into a URI-safe format
*
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(encodeTitleURI("sample text"), "sample_text");
* assertEquals(encodeTitleURI(":title:"), ":title%3A");
* ```
*
* @param title - Title to encode
* @returns A {@linkcode string} containing the URI-safe encoded title
*/
export const encodeTitleURI = (title: string): string => {
return [...title].map((char, index) => {
if (char === " ") return "_";
if (
!noEncodeChars.includes(char) ||
(index === title.length - 1 && noTailChars.includes(char))
) {
return encodeURIComponent(char);
}
return char;
}).join("");
};
const noEncodeChars = '@$&+=:;",';
const noTailChars = ':;",';
/** Convert a title to a URI-safe format while minimizing percent encoding
*
* @example Only words
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(
* toReadableTitleURI("Normal_TitleAAA"),
* "Normal_TitleAAA",
* );
* ```
*
* @example With spaces
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(
* toReadableTitleURI("Title with Spaces"),
* "Title_with_Spaces",
* );
* ```
*
* @example With special characters
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(
* toReadableTitleURI("Title with special characters: /?{}^|<>%"),
* "Title_with_special_characters:_%2F%3F%7B%7D%5E%7C%3C%3E%25",
* );
* ```
*
* @example With multibyte characters
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(
* toReadableTitleURI("日本語_(絵文字✨つき) タイトル"),
* "日本語_(絵文字✨つき) タイトル",
* );
* ```
*
* @example With percent encoding
* ```ts
* import { assertEquals } from "@std/assert/equals";
*
* assertEquals(
* toReadableTitleURI("スラッシュ/は/percent encoding対象の/文字です"),
* "スラッシュ%2Fは%2Fpercent_encoding対象の%2F文字です",
* );
* assertEquals(
* toReadableTitleURI("%2Fなども/と同様percent encodingされる"),
* "%252Fなども%2Fと同様percent_encodingされる",
* );
* ```
*
* @param title - Title to convert
* @returns A {@linkcode string} containing the URI-safe title with minimal percent encoding
*/
export const toReadableTitleURI = (title: string): string => {
return title.replaceAll(" ", "_")
.replace(/[/?#\{}^|<>%]/g, (char) => encodeURIComponent(char));
};