Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: sindresorhus/slugify
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.10.1
Choose a base ref
...
head repository: sindresorhus/slugify
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.11.0
Choose a head ref
  • 2 commits
  • 7 files changed
  • 1 contributor

Commits on Feb 17, 2020

  1. Use @sindresorhus/transliterate

    Fixes #44
    Fixes #41
    Fixes #38
    Fixes #34
    sindresorhus committed Feb 17, 2020
    Copy the full SHA
    aa5f88e View commit details
  2. 0.11.0

    sindresorhus committed Feb 17, 2020
    Copy the full SHA
    f1acfc9 View commit details
Showing with 54 additions and 423 deletions.
  1. +15 −8 index.d.ts
  2. +10 −24 index.js
  3. +1 −1 license
  4. +5 −11 package.json
  5. +22 −8 readme.md
  6. +0 −370 replacements.js
  7. +1 −1 test.js
23 changes: 15 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -53,9 +53,12 @@ declare namespace slugify {
readonly decamelize?: boolean;

/**
Specifying this only replaces the default if you set an item with the same key, like `&`.
Add your own custom replacements.
The replacements are run on the original string before any other transformations.
This only overrides a default replacement if you set an item with the same key, like `&`.
Add a leading and trailing space to the replacement to have it separated by dashes.
@default [ ['&', ' and '], ['🦄', ' unicorn '], ['♥', ' love '] ]
@@ -77,12 +80,20 @@ declare namespace slugify {
]
});
//=> 'foo-at-unicorn'
slugify('I love 🐶', {
customReplacements: [
['🐶', 'dogs']
]
});
//=> 'i-love-dogs'
```
*/
readonly customReplacements?: ReadonlyArray<[string, string]>;

/**
If your string starts with an underscore, it will be preserved in the slugified string.
If your string starts with an underscore, it will be preserved in the slugified string.
Sometimes leading underscores are intentional, for example, filenames representing hidden paths on a website.
@default false
@@ -120,12 +131,8 @@ slugify(' Déjà Vu! ');
slugify('fooBar 123 $#%');
//=> 'foo-bar-123'
slugify('I ♥ 🦄 & 🐶', {
customReplacements: [
['🐶', 'dog']
]
});
//=> 'i-love-unicorn-and-dog'
slugify('я люблю единорогов');
//=> 'ya-lyublyu-edinorogov'
```
*/
declare function slugify(
34 changes: 10 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';
const deburr = require('lodash.deburr');
const escapeStringRegexp = require('escape-string-regexp');
const builtinReplacements = require('./replacements');
const transliterate = require('@sindresorhus/transliterate');
const builtinOverridableReplacements = require('./overridable-replacements');

const decamelize = string => {
@@ -14,21 +13,15 @@ const decamelize = string => {
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1 $2');
};

const doCustomReplacements = (string, replacements) => {
for (const [key, value] of replacements) {
string = string.replace(new RegExp(escapeStringRegexp(key), 'g'), value);
}

return string;
};

const removeMootSeparators = (string, separator) => {
const escapedSeparator = escapeStringRegexp(separator);

return string
.replace(new RegExp(`${separator}{2,}`, 'g'), separator)
.replace(new RegExp(`^${separator}|${separator}$`, 'g'), '');
.replace(new RegExp(`${escapedSeparator}{2,}`, 'g'), separator)
.replace(new RegExp(`^${escapedSeparator}|${escapedSeparator}$`, 'g'), '');
};

const slugify = (string, options) => {
module.exports = (string, options) => {
if (typeof string !== 'string') {
throw new TypeError(`Expected a string, got \`${typeof string}\``);
}
@@ -44,17 +37,12 @@ const slugify = (string, options) => {

const shouldPrependUnderscore = options.preserveLeadingUnderscore && string.startsWith('_');

const separator = escapeStringRegexp(options.separator);

const customReplacements = new Map([
...builtinOverridableReplacements,
...options.customReplacements,
...builtinReplacements
...options.customReplacements
]);

string = doCustomReplacements(string, customReplacements);
string = deburr(string);
string = string.normalize('NFKD');
string = transliterate(string, {customReplacements});

if (options.decamelize) {
string = decamelize(string);
@@ -67,15 +55,13 @@ const slugify = (string, options) => {
patternSlug = /[^a-z\d]+/g;
}

string = string.replace(patternSlug, separator);
string = string.replace(patternSlug, options.separator);
string = string.replace(/\\/g, '');
string = removeMootSeparators(string, separator);
string = removeMootSeparators(string, options.separator);

if (shouldPrependUnderscore) {
string = `_${string}`;
}

return string;
};

module.exports = slugify;
2 changes: 1 addition & 1 deletion license
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

16 changes: 5 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@sindresorhus/slugify",
"version": "0.10.1",
"version": "0.11.0",
"description": "Slugify a string",
"license": "MIT",
"repository": "sindresorhus/slugify",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
"url": "https://sindresorhus.com"
},
"engines": {
"node": ">=10"
@@ -19,7 +19,6 @@
"files": [
"index.js",
"index.d.ts",
"replacements.js",
"overridable-replacements.js"
],
"keywords": [
@@ -42,17 +41,12 @@
"id"
],
"dependencies": {
"escape-string-regexp": "^2.0.0",
"lodash.deburr": "^4.1.0"
"@sindresorhus/transliterate": "^0.1.0",
"escape-string-regexp": "^2.0.0"
},
"devDependencies": {
"ava": "^2.4.0",
"tsd": "^0.11.0",
"xo": "^0.25.3"
},
"xo": {
"rules": {
"prefer-named-capture-group": "off"
}
"xo": "^0.26.1"
}
}
30 changes: 22 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
Useful for URLs, filenames, and IDs.

It correctly handles [German umlauts](https://en.wikipedia.org/wiki/Germanic_umlaut), Vietnamese, Arabic, Russian, Romanian, Turkish, and more.
It handles most major languages, including [German (umlauts)](https://en.wikipedia.org/wiki/Germanic_umlaut), Vietnamese, Arabic, Russian, [and more](https://github.com/sindresorhus/transliterate#supported-languages).

## Install

@@ -26,12 +26,8 @@ slugify(' Déjà Vu! ');
slugify('fooBar 123 $#%');
//=> 'foo-bar-123'

slugify('I ♥ 🦄 & 🐶', {
customReplacements: [
['🐶', 'dog']
]
});
//=> 'i-love-unicorn-and-dog'
slugify('я люблю единорогов');
//=> 'ya-lyublyu-edinorogov'
```

## API
@@ -106,7 +102,11 @@ Default: `[
['♥', ' love ']
]`

Specifying this only replaces the default if you set an item with the same key, like `&`. The replacements are run on the original string before any other transformations.
Add your own custom replacements.

The replacements are run on the original string before any other transformations.

This only overrides a default replacement if you set an item with the same key, like `&`.

```js
const slugify = require('@sindresorhus/slugify');
@@ -132,6 +132,19 @@ slugify('foo@unicorn', {
//=> 'foo-at-unicorn'
```

Another example:

```js
const slugify = require('@sindresorhus/slugify');

slugify('I love 🐶', {
customReplacements: [
['🐶', 'dogs']
]
});
//=> 'i-love-dogs'
```

##### preserveLeadingUnderscore

Type: `boolean`\
@@ -154,4 +167,5 @@ slugify('_foo_bar', {preserveLeadingUnderscore: true});
## Related

- [slugify-cli](https://github.com/sindresorhus/slugify-cli) - CLI for this module
- [transliterate](https://github.com/sindresorhus/transliterate) - Convert Unicode characters to Latin characters using transliteration
- [filenamify](https://github.com/sindresorhus/filenamify) - Convert a string to a valid safe filename
370 changes: 0 additions & 370 deletions replacements.js

This file was deleted.

2 changes: 1 addition & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ test('supports Russian', t => {
});

test('supports Romanian', t => {
t.is(slugify('ș Ț', {lowercase: false, separator: ' '}), 's t');
t.is(slugify('ș Ț', {lowercase: false, separator: ' '}), 's T');
});

test('supports Turkish', t => {