Skip to content

Commit d3aab41

Browse files
committed
🐛 with toSlugCase()
1 parent c14fc3e commit d3aab41

File tree

4 files changed

+49
-9
lines changed

4 files changed

+49
-9
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ xstring.tverskyDistance('pikachu', 'raichu', 3, 0.2, 0.4);
4848
| [toSnakeCase] | Convert a string to snake-case. |
4949
| [toCamelCase] | Convert a string to camel-case. |
5050
| [toPascalCase] | Convert a string to pascal-case. |
51+
| [toSlugCase] | Convert a string to slug-case (URL-friendly kebab-case). |
5152
| | |
5253
| [toBaseline] | Convert a string to baseline characters (limited support). |
5354
| [toSuperscript] | Convert a string to superscript characters (limited support). |
@@ -274,6 +275,7 @@ As of 26 June 2025, this project is licensed under AGPL-3.0. Previous versions r
274275
[toSnakeCase]: https://jsr.io/@nodef/extra-string/doc/~/toSnakeCase
275276
[toCamelCase]: https://jsr.io/@nodef/extra-string/doc/~/toCamelCase
276277
[toPascalCase]: https://jsr.io/@nodef/extra-string/doc/~/toPascalCase
278+
[toSlugCase]: https://jsr.io/@nodef/extra-string/doc/~/toSlugCase
277279
[ngrams]: https://jsr.io/@nodef/extra-string/doc/~/ngrams
278280
[uniqueNgrams]: https://jsr.io/@nodef/extra-string/doc/~/uniqueNgrams
279281
[countNgrams]: https://jsr.io/@nodef/extra-string/doc/~/countNgrams

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nodef/extra-string",
3-
"version": "0.2.0",
3+
"version": "0.2.1",
44
"license": "AGPL-3.0",
55
"exports": "./index.ts",
66
"exclude": [".github/"]

index.test.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
longestCommonSuffix,
4646
longestUncommonInfixes,
4747
toKebabCase,
48+
toSlugCase,
4849
toSuperscript,
4950
tverskyDistance,
5051
} from "./index.ts";
@@ -1228,14 +1229,36 @@ Deno.test("longestUncommonInfixes", () => {
12281229
Deno.test("toKebabCase", () => {
12291230
const a = toKebabCase("Malwa Plateau");
12301231
assertEquals(a, "malwa-plateau");
1231-
const b = toKebabCase("::chota::nagpur::", null, "_");
1232-
assertEquals(b, "chota_nagpur");
1233-
const c = toKebabCase("deccan___plateau", /_+/g, ".");
1234-
assertEquals(c, "deccan.plateau");
1235-
const d = toKebabCase("Some text_with-mixed CASE");
1236-
assertEquals(d, "some-text-with-mixed-case");
1237-
const e = toKebabCase("IAmListeningToFMWhileLoadingDifferentURL");
1238-
assertEquals(e, "i-am-listening-to-fm-while-loading-different-url");
1232+
const b = toKebabCase("malwaPlateau");
1233+
assertEquals(b, "malwa-plateau");
1234+
const c = toKebabCase("::chota::nagpur::", null, "_");
1235+
assertEquals(c, "chota_nagpur");
1236+
const d = toKebabCase("deccan___plateau", /_+/g, ".");
1237+
assertEquals(d, "deccan.plateau");
1238+
const e = toKebabCase("Some text_with-mixed CASE");
1239+
assertEquals(e, "some-text-with-mixed-case");
1240+
const f = toKebabCase("someTextWithMixedCase");
1241+
assertEquals(f, "some-text-with-mixed-case");
1242+
const g = toKebabCase("IAmListeningToFMWhileLoadingDifferentURL");
1243+
assertEquals(g, "i-am-listening-to-fm-while-loading-different-url");
1244+
// const h = toKebabCase("I can't believe it's not butter!");
1245+
// assertEquals(h, "i-cant-believe-its-not-butter");
1246+
});
1247+
1248+
1249+
1250+
1251+
Deno.test("toSlugCase", () => {
1252+
const a = toSlugCase("Malwa Plateau");
1253+
assertEquals(a, "malwa-plateau");
1254+
const b = toSlugCase("malwaPlateau");
1255+
assertEquals(b, "malwa-plateau");
1256+
const c = toSlugCase("Curaçao São Tomé & Príncipe!");
1257+
assertEquals(c, "curacao-sao-tome-principe");
1258+
const d = toSlugCase("你好世界 hello world");
1259+
assertEquals(d, "hello-world");
1260+
// const e = toSlugCase("Æther & Œuvre — résumé", null, "_");
1261+
// assertEquals(e, "aether_oeuvre_resume");
12391262
});
12401263

12411264

index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,21 @@ export function toCamelCase(x: string, re: RegExp | null=null, upper: boolean=fa
14451445
export function toPascalCase(x: string, re: RegExp | null=null): string {
14461446
return toCamelCase(x, re, true);
14471447
}
1448+
1449+
1450+
/**
1451+
* Convert a string to slug-case (URL-friendly kebab-case).
1452+
* @param x a string
1453+
* @param re word separator pattern [/[^0-9A-Za-z]+/g]
1454+
* @param sep separator to join with [-]
1455+
* @returns slug-case | slug<join>case
1456+
*/
1457+
export function toSlugCase(x: string, re: RegExp | null = null, sep: string = "-"): string {
1458+
x = x.normalize("NFKD").replace(/[\u0300-\u036f]/g, ""); // Remove accents
1459+
// deno-lint-ignore no-control-regex
1460+
return toKebabCase(x.replace(/[^\x00-\x7F]/g, ""), re, sep); // Remove non-ASCII chars
1461+
}
1462+
export {toSlugCase as slugify};
14481463
//#endregion
14491464

14501465

0 commit comments

Comments
 (0)