From 565334c069c7639c6f1e14f0897d09279e49a0c8 Mon Sep 17 00:00:00 2001 From: tomaski Date: Tue, 27 Jun 2023 10:10:10 +0300 Subject: [PATCH 1/4] Add `preserve` option to allow preserving additional characters in strict mode --- slugify.d.ts | 1 + slugify.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/slugify.d.ts b/slugify.d.ts index e20f795..773e005 100644 --- a/slugify.d.ts +++ b/slugify.d.ts @@ -16,6 +16,7 @@ declare function slugify( strict?: boolean; locale?: string; trim?: boolean; + preserve?: string[]; } | string, diff --git a/slugify.js b/slugify.js index f5a6a1e..041c6a5 100644 --- a/slugify.js +++ b/slugify.js @@ -43,7 +43,9 @@ }, ''); if (options.strict) { - slug = slug.replace(/[^A-Za-z0-9\s]/g, ''); + const preserveCharacters = options.preserve ? `\\${options.preserve.join('\\')}` : ''; + const regex = new RegExp(`[^A-Za-z0-9${preserveCharacters}\\s]`, 'g'); + slug = slug.replace(regex, ''); } if (trim) { From cebda42a64cb0fc088ec350df255462afb158aa3 Mon Sep 17 00:00:00 2001 From: tomaski Date: Tue, 27 Jun 2023 10:21:16 +0300 Subject: [PATCH 2/4] Add a test for preserve --- test/slugify.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/slugify.js b/test/slugify.js index e2581d2..9740ad3 100644 --- a/test/slugify.js +++ b/test/slugify.js @@ -76,6 +76,14 @@ describe('slugify', () => { t.equal(slugify('foo @ bar', {strict: true}), 'foo-bar') }) + it('options.strict, options.preserve and options.replacement', () => { + t.equal(slugify('!foo.bar_baz@#~', { + replacement: '_', + strict: true, + preserve: ['.'] + }), 'foo.bar_baz') + }) + it('options.replacement and options.strict', () => { t.equal(slugify('foo_@_bar-baz!', { replacement: '_', From 80d9d2351860ee24f3256eec5c0776070fbcc0b9 Mon Sep 17 00:00:00 2001 From: tomaski Date: Tue, 27 Jun 2023 11:13:34 +0300 Subject: [PATCH 3/4] Add preserve to non-strict mode --- slugify.js | 12 ++++++++---- test/slugify.js | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/slugify.js b/slugify.js index 041c6a5..a4ca2ce 100644 --- a/slugify.js +++ b/slugify.js @@ -30,6 +30,8 @@ var trim = options.trim === undefined ? true : options.trim + var preserve = options.preserve === undefined ? [] : `\\${options.preserve.join('\\')}`; + var slug = string.normalize().split('') // replace characters based on charMap .reduce(function (result, ch) { @@ -37,15 +39,17 @@ if (appendChar === undefined) appendChar = charMap[ch]; if (appendChar === undefined) appendChar = ch; if (appendChar === replacement) appendChar = ' '; + + const regexp = new RegExp(`[^\\w\\s$*_+~.()'"!\\-:@${preserve}]+`, 'g') + return result + appendChar // remove not allowed characters - .replace(options.remove || /[^\w\s$*_+~.()'"!\-:@]+/g, '') + .replace(options.remove || regexp, '') }, ''); if (options.strict) { - const preserveCharacters = options.preserve ? `\\${options.preserve.join('\\')}` : ''; - const regex = new RegExp(`[^A-Za-z0-9${preserveCharacters}\\s]`, 'g'); - slug = slug.replace(regex, ''); + const regexp = new RegExp(`[^A-Za-z0-9${preserve}\\s]`, 'g') + slug = slug.replace(regexp, '') } if (trim) { diff --git a/test/slugify.js b/test/slugify.js index 9740ad3..11f4372 100644 --- a/test/slugify.js +++ b/test/slugify.js @@ -68,6 +68,10 @@ describe('slugify', () => { t.equal(slugify('Foo bAr baZ', {lower: true}), 'foo-bar-baz') }) + it('options.preserve', () => { + t.equal(slugify('/url/to/foo bar baz', {preserve: ['/']}), '/url/to/foo-bar-baz') + }); + it('options.strict', () => { t.equal(slugify('foo_bar. -@-baz!', {strict: true}), 'foobar-baz') }) From ec94d65ac6fd4da01dac499e444c250770b8104a Mon Sep 17 00:00:00 2001 From: tomaski Date: Tue, 27 Jun 2023 12:41:43 +0300 Subject: [PATCH 4/4] Readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 385d7b0..7197294 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ slugify('some string', { strict: false, // strip special characters except replacement, defaults to `false` locale: 'vi', // language code of the locale to use trim: true // trim leading and trailing replacement chars, defaults to `true` + preserve: ['.'] // preserve specified characters in the result }) ```