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 }) ``` 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..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,13 +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) { - slug = slug.replace(/[^A-Za-z0-9\s]/g, ''); + 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 e2581d2..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') }) @@ -76,6 +80,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: '_',