Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

speakingurl

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

speakingurl - npm Package Compare versions

Comparing version 0.1.7 to 0.2.1

test/test-symbols.js

69

examples/makeSpeakingUrl.js
var getSlug = require('../lib'),
slug;
slug = getSlug("Das ist ein schöner Titel, der keine Wünsche offen läßt!");
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !");
console.log(slug);
// Output: "moechtest-du-eine-schoene-url"
console.log("\n");
// Output: schoener-titel-laesst-gruessen-bel-ete
slug = getSlug("C'est un beau titre qui ne laisse rien à désirer!");
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", "*");
console.log(slug);
// Output: "cest-un-beau-titre-qui-ne-laisse-rien-a-desirer"
console.log("\n");
// Output: schoener*titel*laesst*gruessen*bel*ete
// optionally allow RFC3986 conform url path, default base64 /A-Za-z0-9_-/
slug = getSlug("Allow *RFC396* characters like 'that'?", {rfc3986: true} );
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {separator: "_"});
console.log(slug);
// Output: "allow-*rfc396*-characters-like-'that'"
console.log("\n");
// Output: schoener_titel_laesst_gruessen_bel_ete
// if you choose a separator which is'nt a Base64 (/A-Za-z0-9_-/) character => rfc3986 == true
slug = getSlug("Choosing 'separator' to non Base64 char, rfc3986 chars are allowed at all", {separator: '*'} );
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {uric: true});
console.log(slug);
// Output: "choosing*'separator'*to*non*base64*char,*rfc3986*chars*are*allowed*at*all"
console.log("\n");
// Output: schoener-titel-laesst-gruessen?-bel-ete
// optionally use a different separator character
slug = getSlug("Would you like another seaprator?", {separator: '_'} );
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {uricNoSlash: true});
console.log(slug);
// Output: "would_you_like_another_character"
console.log("\n");
// Output: schoener-titel-laesst-gruessen?-bel-ete
// optionally maintain case
slug = getSlug("Don't convert UPPERCASE chars", {maintainCase: true});
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {mark: true});
console.log(slug);
// Output: "Do-not-convert-UPPERCASE-chars"
console.log("\n");
// Output: schoener-titel-laesst-gruessen!-bel-ete-!
// optionally trim to max length while not breaking any words
slug = getSlug("Trim sentence ... to fit in length", {smartTrim: 16});
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {truncate: 20});
console.log(slug);
// Output: "trim-sentence-to"
console.log("\n");
// Output: schoener-titel
// optionally allow RFC3986 conform url path with smart trim
slug = getSlug("Allow *RFC3986* characters like 'that'?", {rfc3986: true, smartTrim: 20} );
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {maintainCase: true});
console.log(slug);
// Output: "allow-*rfc396*"
console.log("\n");
// Output: Schoener-Titel-laesst-gruessen-Bel-ete
slug = getSlug("Apfel & Birne!", {lang: 'de'});
console.log(slug);
console.log("\n");
// Output: apfel-und-birne
slug = getSlug('Foo & Bar * Baz', {custom: {'&': ' doo '}, uric:true } );
console.log(slug);
console.log("\n");
// Output: foo-doo-bar-baz
slug = getSlug('Foo ♥ Bar');
console.log(slug);
console.log("\n");
// Output: foo-love-bar
slug = getSlug('Foo & Bar | Baz * Doo', {custom:{'*': "Boo"},mark:true});
console.log(slug);
console.log("\n");
// Output: foo-and-bar-or-baz-boo-doo
//

@@ -1,1 +0,1 @@

module.exports = require('./speakingurl');
module.exports = require('lib/');

@@ -1,1 +0,508 @@

module.exports = require('../speakingurl');
(function () {
var charMap = {
// latin
'À': 'A',
'Á': 'A',
'Â': 'A',
'Ã': 'A',
'Ä': 'A',
'Å': 'A',
'Æ': 'AE',
'Ç': 'C',
'È': 'E',
'É': 'E',
'Ê': 'E',
'Ë': 'E',
'Ì': 'I',
'Í': 'I',
'Î': 'I',
'Ï': 'I',
'Ð': 'D',
'Ñ': 'N',
'Ò': 'O',
'Ó': 'O',
'Ô': 'O',
'Õ': 'O',
'Ö': 'Oe',
'Ő': 'O',
'Ø': 'O',
'Ù': 'U',
'Ú': 'U',
'Û': 'U',
'Ü': 'Ue',
'Ű': 'U',
'Ý': 'Y',
'Þ': 'TH',
'ß': 'ss',
'à': 'a',
'á': 'a',
'â': 'a',
'ã': 'a',
'ä': 'ae',
'å': 'a',
'æ': 'ae',
'ç': 'c',
'è': 'e',
'é': 'e',
'ê': 'e',
'ë': 'e',
'ì': 'i',
'í': 'i',
'î': 'i',
'ï': 'i',
'ð': 'd',
'ñ': 'n',
'ò': 'o',
'ó': 'o',
'ô': 'o',
'õ': 'o',
'ö': 'oe',
'ő': 'o',
'ø': 'o',
'ù': 'u',
'ú': 'u',
'û': 'u',
'ü': 'ue',
'ű': 'u',
'ý': 'y',
'þ': 'th',
'ÿ': 'y',
'ẞ': 'SS',
// greek
'α': 'a',
'β': 'b',
'γ': 'g',
'δ': 'd',
'ε': 'e',
'ζ': 'z',
'η': 'h',
'θ': '8',
'ι': 'i',
'κ': 'k',
'λ': 'l',
'μ': 'm',
'ν': 'n',
'ξ': '3',
'ο': 'o',
'π': 'p',
'ρ': 'r',
'σ': 's',
'τ': 't',
'υ': 'y',
'φ': 'f',
'χ': 'x',
'ψ': 'ps',
'ω': 'w',
'ά': 'a',
'έ': 'e',
'ί': 'i',
'ό': 'o',
'ύ': 'y',
'ή': 'h',
'ώ': 'w',
'ς': 's',
'ϊ': 'i',
'ΰ': 'y',
'ϋ': 'y',
'ΐ': 'i',
'Α': 'A',
'Β': 'B',
'Γ': 'G',
'Δ': 'D',
'Ε': 'E',
'Ζ': 'Z',
'Η': 'H',
'Θ': '8',
'Ι': 'I',
'Κ': 'K',
'Λ': 'L',
'Μ': 'M',
'Ν': 'N',
'Ξ': '3',
'Ο': 'O',
'Π': 'P',
'Ρ': 'R',
'Σ': 'S',
'Τ': 'T',
'Υ': 'Y',
'Φ': 'F',
'Χ': 'X',
'Ψ': 'PS',
'Ω': 'W',
'Ά': 'A',
'Έ': 'E',
'Ί': 'I',
'Ό': 'O',
'Ύ': 'Y',
'Ή': 'H',
'Ώ': 'W',
'Ϊ': 'I',
'Ϋ': 'Y',
//turkish
'ş': 's',
'Ş': 'S',
'ı': 'i',
'İ': 'I',
'ç': 'c',
'Ç': 'C',
'ü': 'ue',
'Ü': 'Ue',
'ö': 'oe',
'Ö': 'Oe',
'ğ': 'g',
'Ğ': 'G',
// russian
'а': 'a',
'б': 'b',
'в': 'v',
'г': 'g',
'д': 'd',
'е': 'e',
'ё': 'yo',
'ж': 'zh',
'з': 'z',
'и': 'i',
'й': 'j',
'к': 'k',
'л': 'l',
'м': 'm',
'н': 'n',
'о': 'o',
'п': 'p',
'р': 'r',
'с': 's',
'т': 't',
'у': 'u',
'ф': 'f',
'х': 'h',
'ц': 'c',
'ч': 'ch',
'ш': 'sh',
'щ': 'sh',
'ъ': 'u',
'ы': 'y',
'ь': '',
'э': 'e',
'ю': 'yu',
'я': 'ya',
'А': 'A',
'Б': 'B',
'В': 'V',
'Г': 'G',
'Д': 'D',
'Е': 'E',
'Ё': 'Yo',
'Ж': 'Zh',
'З': 'Z',
'И': 'I',
'Й': 'J',
'К': 'K',
'Л': 'L',
'М': 'M',
'Н': 'N',
'О': 'O',
'П': 'P',
'Р': 'R',
'С': 'S',
'Т': 'T',
'У': 'U',
'Ф': 'F',
'Х': 'H',
'Ц': 'C',
'Ч': 'Ch',
'Ш': 'Sh',
'Щ': 'Sh',
'Ъ': 'U',
'Ы': 'Y',
'Ь': '',
'Э': 'E',
'Ю': 'Yu',
'Я': 'Ya',
// ukranian
'Є': 'Ye',
'І': 'I',
'Ї': 'Yi',
'Ґ': 'G',
'є': 'ye',
'і': 'i',
'ї': 'yi',
'ґ': 'g',
// czech
'č': 'c',
'ď': 'd',
'ě': 'e',
'ň': 'n',
'ř': 'r',
'š': 's',
'ť': 't',
'ů': 'u',
'ž': 'z',
'Č': 'C',
'Ď': 'D',
'Ě': 'E',
'Ň': 'N',
'Ř': 'R',
'Š': 'S',
'Ť': 'T',
'Ů': 'U',
'Ž': 'Z',
// polish
'ą': 'a',
'ć': 'c',
'ę': 'e',
'ł': 'l',
'ń': 'n',
'ó': 'o',
'ś': 's',
'ź': 'z',
'ż': 'z',
'Ą': 'A',
'Ć': 'C',
'Ę': 'e',
'Ł': 'L',
'Ń': 'N',
'Ś': 'S',
'Ź': 'Z',
'Ż': 'Z',
// latvian
'ā': 'a',
'č': 'c',
'ē': 'e',
'ģ': 'g',
'ī': 'i',
'ķ': 'k',
'ļ': 'l',
'ņ': 'n',
'š': 's',
'ū': 'u',
'ž': 'z',
'Ā': 'A',
'Č': 'C',
'Ē': 'E',
'Ģ': 'G',
'Ī': 'i',
'Ķ': 'k',
'Ļ': 'L',
'Ņ': 'N',
'Š': 'S',
'Ū': 'u',
'Ž': 'Z',
// symbols
'“': '"',
'”': '"',
'‘': "'",
'’': "'",
'∂': 'd',
'ƒ': 'f',
'™': '(tm)',
'©': '(c)',
'œ': 'oe',
'Œ': 'OE',
'®': '(r)',
'†': '+',
'℠': '(sm)',
'…': '...',
'˚': 'o',
'º': 'o',
'ª': 'a',
'•': '*',
// currency
"$": 'USD',
'€': 'EUR',
'₢': 'BRN',
'₣': 'FRF',
'£': 'GBP',
'₤': 'ITL',
'₦': 'NGN',
'₧': 'ESP',
'₨': 'INR',
'₩': 'KRW',
'₪': 'ILS',
'₫': 'VND',
'₭': 'LAK',
'₮': 'MNT',
'₯': 'GRD',
'₱': 'ARS',
'₲': 'PYG',
'₳': 'ARA',
'₴': 'UAH',
'₵': 'GHS',
'¢': 'cent',
'¥': 'CNY',
'元': 'CNY',
'円': 'YEN',
'﷼': 'IRR',
'₠': 'EWE',
'฿': 'THB'
};
var symbolMap = {
'en': {
'∆': 'delta',
'∞': 'infinity',
'♥': 'love',
'&': 'and',
'|': 'or',
'<': 'less than',
'>': 'greater than',
'∑': 'sum',
'¤': 'currency'
},
'de': {
'∆': 'delta',
'∞': 'unendlich',
'♥': 'Liebe',
'&': 'und',
'|': 'oder',
'<': 'kleiner als',
'>': 'groesser als',
'∑': 'Summe von',
'¤': 'Waehrung'
},
'fr': {
'∆': 'delta',
'∞': 'infiniment',
'♥': 'Amour',
'&': 'et',
'|': 'ou',
'<': 'moins que',
'>': 'superieure a',
'∑': 'somme des',
'¤': 'monnaie'
},
'es': {
'∆': 'delta',
'∞': 'infinito',
'♥': 'amor',
'&': 'y',
'|': 'u',
'<': 'menos que',
'>': 'mas que',
'∑': 'suma de los',
'¤': 'moneda'
},
'ru': {
'∆': 'delta',
'∞': 'infinity',
'♥': 'love',
'&': 'and',
'|': 'or',
'<': 'less than',
'>': 'greater than',
'∑': 'sum',
'¤': 'currency'
}
}
var getSlug = function getSlug(string, opts) {
var maintainCase = typeof opts === 'object' && opts.maintainCase || false,
separator = typeof opts === 'object' && opts.separator || '-',
truncate = typeof opts === 'object' && opts.truncate,
language = typeof opts === 'object' && opts.lang || 'en',
uricFlag = typeof opts === 'object' && opts.uric || false,
uricNoSlashFlag = typeof opts === 'object' && opts.uricNoSlash || false,
markFlag = typeof opts === 'object' && opts.mark || false,
symbol = symbolMap[language],
customChars = typeof opts === 'object' && opts.custom || {},
uricChars = [';', '?', ':', '@', '&', '=', '+', '$', ',', '/'],
uricNoSlashChars = [';', '?', ':', '@', '&', '=', '+', '$', ','],
markChars = ['.', '!', '~', '*', '\'', '(', ')'],
result = '',
lucky,
allowedChars = [],
i,
ch,
l,
lastCharWasSpecial;
if (typeof string !== 'string') {
return '';
}
if (typeof opts === 'string') {
separator = opts;
} else if (typeof opts === 'object') {
if (uricFlag) {
allowedChars = allowedChars.concat(uricChars);
}
if (uricNoSlashFlag) {
allowedChars = allowedChars.concat(uricNoSlashChars);
}
if (markFlag) {
allowedChars = allowedChars.concat(markChars);
}
}
allowedChars = (allowedChars.join('') + separator).replace(/[-\\^$*+?.()|[\]{}\/]/g, "\\$&");
// trim whitspaces
string = string.replace(/(^\s+|\s+$)/g, '');
lastCharWasSymbol = false;
for (i = 0, l = string.length; i < l; i++) {
ch = string[i];
if (customChars[ch]) {
ch = lastCharWasSymbol && customChars[ch].match(/[A-Za-z]/) ? ' ' + customChars[ch] : customChars[ch];
lastCharWasSymbol = false;
} else if (charMap[ch]) {
ch = lastCharWasSymbol && charMap[ch].match(/[A-Za-z]/) ? ' ' + charMap[ch] : charMap[ch];
lastCharWasSymbol = false;
} else if (
symbol[ch]
&& !(uricFlag && uricChars.join('').indexOf(ch) !== -1)
&& !(uricNoSlashFlag && uricNoSlashChars.join('').indexOf(ch) !== -1)
&& !(markFlag && markChars.join('').indexOf(ch) !== -1)) {
if(lastCharWasSymbol || (result.length && result[result.length-1].match(/[A-Za-z]/))) {
ch = ' ' + symbol[ch];
} else {
ch = symbol[ch];
}
lastCharWasSymbol = true;
} else {
ch = lastCharWasSymbol && ch.match(/[A-Za-z]/) || (result.length && result[result.length-1].match(/[^\d]/) && ch.match(/[\d]/)) ? ' ' + ch : ch;
lastCharWasSymbol = false;
}
// add allowed chars
result += ch.replace(new RegExp('[^A-Za-z0-9-_\\w\\s' + allowedChars + '-]', 'g'), '');
}
result = result
// eliminate duplicate separators
.replace(/\s+/g, separator)
// add separator
.replace(new RegExp('\\' + separator + '+', 'g'), separator)
// trim separators from start and end
.replace(new RegExp('(^\\' + separator + '+|\\' + separator + '+$)', 'g'), '');
if (truncate && result.length > truncate) {
lucky = result.charAt(truncate) === separator;
result = result.slice(0, truncate);
if (!lucky) {
result = result.slice(0, result.lastIndexOf(separator));
}
}
if (!maintainCase) {
result = result.toLowerCase();
}
return result;
}
if (typeof module !== 'undefined') {
module.exports = getSlug;
} else {
window.getSlug = getSlug;
}
})();
{
"name": "speakingurl",
"version": "0.1.7",
"version": "0.2.1",
"description": "Generate of so called 'static' or 'nice-looking' or 'SpeakingURL' or 'slug' from a string.",

@@ -19,3 +19,3 @@ "keywords": [

},
"main": "speakingurl",
"main": "index",
"dependencies": {},

@@ -22,0 +22,0 @@ "devDependencies": {

# Speaking URL [![NPM version](https://badge.fury.io/js/speakingurl.png)](http://badge.fury.io/js/speakingurl)
Generate of so called "static" or "nice-looking" or "SpeakingURL" or "slug" from a string.
Works in browser and on node-server
For use in browser and server.
#### Notes
In v0.1.x converting symbols is disabled, should be added in v0.2.x (see [Issues](https://github.com/pid/speakingurl/issues))
This is an early version, please check for your needs and give feedback to improve it.
## Installation

@@ -15,19 +11,30 @@ $ npm install speakingurl

### getSlug(input, [options]);
```input```: string to convert; ```options```: config object (see below)
```input```: {string} to convert; ```options```: {object|string} config object or separator string (see below)
* ```separator``` default: '-'
* ```separator``` {string} default: '-'
* char that replace the whitespaces
* ```maintainCase``` default: false
* ```lang``` {string} default: 'en'
* language for symbol translation ('en, 'de', more coming soon)
* ```maintainCase``` {boolean} default: false
* true => maintain case chars
* false => convert all chars to lower case
* ```rfc3986``` default: false
* true => allow chars according to ~RFC3986 for url path
* ```uric``` {boolean} default: false
* true => additionally allow chars: ";", "?", ":", "@", "&", "=", "+", "$", ",", "/"
* false => only Base64 chars allowed (/A-Za-z0-9-_/)
* ```smartTrim``` default: 0
* ```uricNoSlash``` {boolean} default: false
* true => additionally allow chars: ";", "?", ":", "@", "&", "=", "+", "$", ","
* false => only Base64 chars allowed (/A-Za-z0-9-_/)
* ```mark``` {boolean} default: false
* true => additionally allow chars: "-", "_", ".", "!", "~", "*", "'", "(", ")"
* false => only Base64 chars allowed (/A-Za-z0-9-_/)
* ```custom``` {object} default: {}
* custom map for translation, overwrites all i.e. { '&': '#', '*': ' star ' }
* ```truncate``` {number} default: 0
* 0 => don't trim length
* >0 => trim to max length while not breaking any words
* >0 => trim to max length while not breaking any words
notes:
- if you set the ```separator``` to a non-Base64 (/A-Za-z0-9-_/) char, ```rfc3986``` is set to ```true```
* ```options``` {string} separator
notes: default only Base64 chars are allowed (/A-Za-z0-9_-/), setting ```uric```, ```uricNoSlash``` or/and ```mark``` to ```true```will add the specified chars to the allowed chars. The separator-character is always allowed.
## Examples

@@ -38,31 +45,53 @@ ```javascript

slug = getSlug("Das ist ein schöner Titel, der keine Wünsche offen läßt ! ");
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !");
console.log(slug);
// Output: "das-ist-ein-schoener-titel-der-keine-wuensche-offen-laesst"
// Output: schoener-titel-laesst-gruessen-bel-ete
slug = getSlug("C'est un beau titre qui ne laisse rien à désirer ! ");
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", "*");
console.log(slug);
// Output: "cest-un-beau-titre-qui-ne-laisse-rien-a-desirer"
// Output: schoener*titel*laesst*gruessen*bel*ete
// optionally use a different separator character
slug = getSlug("Would you like another character?", {separator: '_'} );
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {separator: "_"});
console.log(slug);
// Output: "want_another_separator"
// Output: schoener_titel_laesst_gruessen_bel_ete
// optionally maintain case
slug = getSlug("Do not convert UPPERCASE chars", {maintainCase: true});
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {uric: true});
console.log(slug);
// Output: "Do-not-convert-UPPERCASE-chars"
// Output: schoener-titel-laesst-gruessen?-bel-ete
// optionally trim to max length while not breaking any words
slug = getSlug("Trim sentence ... to fit in length", {smartTrim: 16});
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {uricNoSlash: true});
console.log(slug);
// Output: "trim-sentence-to"
// Output: schoener-titel-laesst-gruessen?-bel-ete
// optionally allow RFC3986 conform url path, default base64 /A-Za-z0-9_-/
slug = getSlug("Allow *RFC396* characters like 'that'?", {rfc3986: true} );
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {mark: true});
console.log(slug);
// Output: "allow-*rfc396*-characters-like-'that'"
// Output: schoener-titel-laesst-gruessen!-bel-ete-!
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {truncate: 20});
console.log(slug);
// Output: schoener-titel
slug = getSlug("Schöner Titel läßt grüßen!? Bel été !", {maintainCase: true});
console.log(slug);
// Output: Schoener-Titel-laesst-gruessen-Bel-ete
slug = getSlug("Apfel & Birne!", {lang: 'de'});
console.log(slug);
// Output: apfel-und-birne
slug = getSlug('Foo & Bar * Baz', {custom: {'&': ' doo '}, uric:true } );
console.log(slug);
// Output: foo-doo-bar-baz
slug = getSlug('Foo ♥ Bar');
console.log(slug);
// Output: foo-love-bar
slug = getSlug('Foo & Bar | Baz * Doo', {custom:{'*': "Boo"},mark:true});
console.log(slug);
// Output: foo-and-bar-or-baz-boo-doo
```
## Tests

@@ -75,5 +104,9 @@ [![Build Status](https://travis-ci.org/pid/speakingurl.png)](https://travis-ci.org/pid/speakingurl)

## Credits
- @simov https://github.com/simov/slugify
- @henrikjoreteg https://github.com/henrikjoreteg/slugger
- [@dypsilon](https://github.com/dypsilon/js-replace-diacritics)
- [@simov](https://github.com/simov/slugify)
- [@henrikjoreteg](https://github.com/henrikjoreteg/slugger)
## Informations
http://tools.ietf.org/html/rfc3986
## License

@@ -80,0 +113,0 @@ [BSD](https://raw.github.com/pid/speakingurl/master/LICENCE)

@@ -1,1 +0,1 @@

!function(){var charMap={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"Oe","Ő":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"Ue","Ű":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"ae","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"oe","ő":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"ue","ű":"u","ý":"y","þ":"th","ÿ":"y","ẞ":"SS","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ά":"a","έ":"e","ί":"i","ό":"o","ύ":"y","ή":"h","ώ":"w","ς":"s","ϊ":"i","ΰ":"y","ϋ":"y","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ά":"A","Έ":"E","Ί":"I","Ό":"O","Ύ":"Y","Ή":"H","Ώ":"W","Ϊ":"I","Ϋ":"Y","ş":"s","Ş":"S","ı":"i","İ":"I","ç":"c","Ç":"C","ü":"ue","Ü":"Ue","ö":"oe","Ö":"Oe","ğ":"g","Ğ":"G","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ё":"yo","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ё":"Yo","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","Є":"Ye","І":"I","Ї":"Yi","Ґ":"G","є":"ye","і":"i","ї":"yi","ґ":"g","č":"c","ď":"d","ě":"e","ň":"n","ř":"r","š":"s","ť":"t","ů":"u","ž":"z","Č":"C","Ď":"D","Ě":"E","Ň":"N","Ř":"R","Š":"S","Ť":"T","Ů":"U","Ž":"Z","ą":"a","ć":"c","ę":"e","ł":"l","ń":"n","ó":"o","ś":"s","ź":"z","ż":"z","Ą":"A","Ć":"C","Ę":"e","Ł":"L","Ń":"N","Ś":"S","Ź":"Z","Ż":"Z","ā":"a","č":"c","ē":"e","ģ":"g","ī":"i","ķ":"k","ļ":"l","ņ":"n","š":"s","ū":"u","ž":"z","Ā":"A","Č":"C","Ē":"E","Ģ":"G","Ī":"i","Ķ":"k","Ļ":"L","Ņ":"N","Š":"S","Ū":"u","Ž":"Z"};var whitespace=/\s+/g;var getSlug=function getSlug(string,opts){var maintainCase=opts&&opts.maintainCase||false,separator=opts&&opts.separator||"-",smartTrim=opts&&opts.smartTrim,language=opts&&opts.language||"en",onlyBase64=opts&&opts.rfc3986&&!opts.onlyBase64?false:true,onlyBase64=onlyBase64&&/[^_-]/.test(separator)?false:onlyBase64,result="",lucky,i,ch,l;if(typeof string!=="string"){return""}string=string.replace(/(^\s+|\s+$)/g,"");string=string.replace(new RegExp("(^\\"+separator+"+|\\"+separator+"+$)","g"),"");for(i=0,l=string.length;i<l;i++){ch=string[i];if(charMap[ch]){ch=charMap[ch]}if(onlyBase64){ch=ch.replace(/[^A-Za-z0-9_-\s]/g,"")}else{ch=ch.replace(/[^\w\s\-\.\_~\!$\'\(\)\*\,\;:@]/g,"")}result+=ch}result=result.replace(whitespace,separator);if(smartTrim&&result.length>smartTrim){lucky=result.charAt(smartTrim)===separator;result=result.slice(0,smartTrim);if(!lucky){result=result.slice(0,result.lastIndexOf(separator))}}if(!maintainCase){result=result.toLowerCase()}result=result.replace(new RegExp("\\"+separator+"+","g"),separator);return result};if(typeof module!=="undefined"){module.exports=getSlug}else{window.getSlug=getSlug}}();
!function(){var charMap={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"Oe","Ő":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"Ue","Ű":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"ae","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"oe","ő":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"ue","ű":"u","ý":"y","þ":"th","ÿ":"y","ẞ":"SS","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ά":"a","έ":"e","ί":"i","ό":"o","ύ":"y","ή":"h","ώ":"w","ς":"s","ϊ":"i","ΰ":"y","ϋ":"y","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ά":"A","Έ":"E","Ί":"I","Ό":"O","Ύ":"Y","Ή":"H","Ώ":"W","Ϊ":"I","Ϋ":"Y","ş":"s","Ş":"S","ı":"i","İ":"I","ç":"c","Ç":"C","ü":"ue","Ü":"Ue","ö":"oe","Ö":"Oe","ğ":"g","Ğ":"G","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ё":"yo","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ё":"Yo","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","Є":"Ye","І":"I","Ї":"Yi","Ґ":"G","є":"ye","і":"i","ї":"yi","ґ":"g","č":"c","ď":"d","ě":"e","ň":"n","ř":"r","š":"s","ť":"t","ů":"u","ž":"z","Č":"C","Ď":"D","Ě":"E","Ň":"N","Ř":"R","Š":"S","Ť":"T","Ů":"U","Ž":"Z","ą":"a","ć":"c","ę":"e","ł":"l","ń":"n","ó":"o","ś":"s","ź":"z","ż":"z","Ą":"A","Ć":"C","Ę":"e","Ł":"L","Ń":"N","Ś":"S","Ź":"Z","Ż":"Z","ā":"a","č":"c","ē":"e","ģ":"g","ī":"i","ķ":"k","ļ":"l","ņ":"n","š":"s","ū":"u","ž":"z","Ā":"A","Č":"C","Ē":"E","Ģ":"G","Ī":"i","Ķ":"k","Ļ":"L","Ņ":"N","Š":"S","Ū":"u","Ž":"Z","“":'"',"”":'"',"‘":"'","’":"'","∂":"d","ƒ":"f","™":"(tm)","©":"(c)","œ":"oe","Œ":"OE","®":"(r)","†":"+","℠":"(sm)","…":"...","˚":"o","º":"o","ª":"a","•":"*",$:"USD","€":"EUR","₢":"BRN","₣":"FRF","£":"GBP","₤":"ITL","₦":"NGN","₧":"ESP","₨":"INR","₩":"KRW","₪":"ILS","₫":"VND","₭":"LAK","₮":"MNT","₯":"GRD","₱":"ARS","₲":"PYG","₳":"ARA","₴":"UAH","₵":"GHS","¢":"cent","¥":"CNY","元":"CNY","円":"YEN","﷼":"IRR","₠":"EWE","฿":"THB"};var symbolMap={en:{"∆":"delta","∞":"infinity","♥":"love","&":"and","|":"or","<":"less than",">":"greater than","∑":"sum","¤":"currency"},de:{"∆":"delta","∞":"unendlich","♥":"Liebe","&":"und","|":"oder","<":"kleiner als",">":"groesser als","∑":"Summe von","¤":"Waehrung"},fr:{"∆":"delta","∞":"infiniment","♥":"Amour","&":"et","|":"ou","<":"moins que",">":"superieure a","∑":"somme des","¤":"monnaie"},es:{"∆":"delta","∞":"infinito","♥":"amor","&":"y","|":"u","<":"menos que",">":"mas que","∑":"suma de los","¤":"moneda"},ru:{"∆":"delta","∞":"infinity","♥":"love","&":"and","|":"or","<":"less than",">":"greater than","∑":"sum","¤":"currency"}};var getSlug=function getSlug(string,opts){var maintainCase=typeof opts==="object"&&opts.maintainCase||false,separator=typeof opts==="object"&&opts.separator||"-",truncate=typeof opts==="object"&&opts.truncate,language=typeof opts==="object"&&opts.lang||"en",uricFlag=typeof opts==="object"&&opts.uric||false,uricNoSlashFlag=typeof opts==="object"&&opts.uricNoSlash||false,markFlag=typeof opts==="object"&&opts.mark||false,symbol=symbolMap[language],customChars=typeof opts==="object"&&opts.custom||{},uricChars=[";","?",":","@","&","=","+","$",",","/"],uricNoSlashChars=[";","?",":","@","&","=","+","$",","],markChars=[".","!","~","*","'","(",")"],result="",lucky,allowedChars=[],i,ch,l,lastCharWasSpecial;if(typeof string!=="string"){return""}if(typeof opts==="string"){separator=opts}else if(typeof opts==="object"){if(uricFlag){allowedChars=allowedChars.concat(uricChars)}if(uricNoSlashFlag){allowedChars=allowedChars.concat(uricNoSlashChars)}if(markFlag){allowedChars=allowedChars.concat(markChars)}}allowedChars=(allowedChars.join("")+separator).replace(/[-\\^$*+?.()|[\]{}\/]/g,"\\$&");string=string.replace(/(^\s+|\s+$)/g,"");lastCharWasSymbol=false;for(i=0,l=string.length;i<l;i++){ch=string[i];if(customChars[ch]){ch=lastCharWasSymbol&&customChars[ch].match(/[A-Za-z]/)?" "+customChars[ch]:customChars[ch];lastCharWasSymbol=false}else if(charMap[ch]){ch=lastCharWasSymbol&&charMap[ch].match(/[A-Za-z]/)?" "+charMap[ch]:charMap[ch];lastCharWasSymbol=false}else if(symbol[ch]&&!(uricFlag&&uricChars.join("").indexOf(ch)!==-1)&&!(uricNoSlashFlag&&uricNoSlashChars.join("").indexOf(ch)!==-1)&&!(markFlag&&markChars.join("").indexOf(ch)!==-1)){if(lastCharWasSymbol||result.length&&result[result.length-1].match(/[A-Za-z]/)){ch=" "+symbol[ch]}else{ch=symbol[ch]}lastCharWasSymbol=true}else{ch=lastCharWasSymbol&&ch.match(/[A-Za-z]/)||result.length&&result[result.length-1].match(/[^\d]/)&&ch.match(/[\d]/)?" "+ch:ch;lastCharWasSymbol=false}result+=ch.replace(new RegExp("[^A-Za-z0-9-_\\w\\s"+allowedChars+"-]","g"),"")}result=result.replace(/\s+/g,separator).replace(new RegExp("\\"+separator+"+","g"),separator).replace(new RegExp("(^\\"+separator+"+|\\"+separator+"+$)","g"),"");if(truncate&&result.length>truncate){lucky=result.charAt(truncate)===separator;result=result.slice(0,truncate);if(!lucky){result=result.slice(0,result.lastIndexOf(separator))}}if(!maintainCase){result=result.toLowerCase()}return result};if(typeof module!=="undefined"){module.exports=getSlug}else{window.getSlug=getSlug}}();

@@ -5,10 +5,90 @@ // test-rfc3986.js

describe('getSlug RFC3986 characters allowed', function () {
it('should only Base64 characters', function () {
getSlug('Foo, Bar Baz', {rfc3986: true}).should.eql('foo,-bar-baz');
getSlug('Foo- Bar Baz', {rfc3986: true}).should.eql('foo-bar-baz');
getSlug('Foo] Bar Baz', {rfc3986: true}).should.eql('foo-bar-baz');
getSlug('Foo* Bar Baz', {rfc3986: true}).should.eql('foo*-bar-baz');
getSlug('Foo*Bar Baz', {rfc3986: true}).should.eql('foo*bar-baz');
describe('getSlug rfc3986', function () {
it('"uric" characters allowed', function () {
var chars = [';', '?', ':', '@', '&', '=', '+', ',', '/'];
for (var i = 0; i < chars.length; i++) {
getSlug("foo " + chars[i] + " bar baz", {
uric: true
})
.should.eql("foo-" + chars[i] + "-bar-baz");
}
});
});
it('"uricNoSlash" characters allowed', function () {
var chars = [';', '?', ':', '@', '&', '=', '+', ','];
for (var i = 0; i < chars.length; i++) {
getSlug("foo " + chars[i] + " bar baz", {
uricNoSlash: true
})
.should.eql("foo-" + chars[i] + "-bar-baz");
}
});
it('"mark" characters allowed', function () {
var chars = ['.', '!', '~', '*', '\'', '(', ')'];
for (var i = 0; i < chars.length; i++) {
getSlug("foo " + chars[i] + " bar baz", {
mark: true
})
.should.eql("foo-" + chars[i] + "-bar-baz");
}
});
it('"uric" characters allowed, separator ";"', function () {
var chars = ['?', ':', '@', '&', '=', '+', ',', '/'];
for (var i = 0; i < chars.length; i++) {
getSlug("foo " + chars[i] + " bar baz", {
uric: true,
separator: ';'
})
.should.eql("foo;" + chars[i] + ";bar;baz");
}
});
it('"uric" characters allowed, separator ";" included in input string', function () {
getSlug("foo ; bar baz", {
uric: true,
separator: ';'
})
.should.eql("foo;bar;baz");
});
it('"uricNoSlash" characters allowed, separator ";"', function () {
var chars = ['?', ':', '@', '&', '=', '+', ','];
for (var i = 0; i < chars.length; i++) {
getSlug("foo " + chars[i] + " bar baz", {
uricNoSlash: true,
separator: ';'
})
.should.eql("foo;" + chars[i] + ";bar;baz");
}
});
it('"uricNoSlash" characters allowed, separator ";" included in input string', function () {
getSlug("foo ; bar baz", {
uric: true,
separator: ';'
})
.should.eql("foo;bar;baz");
});
it('"mark" characters allowed, separator "."', function () {
var chars = ['!', '~', '*', '\'', '(', ')'];
for (var i = 0; i < chars.length; i++) {
getSlug("foo " + chars[i] + " bar baz", {
mark: true,
separator: '.'
})
.should.eql("foo." + chars[i] + ".bar.baz");
}
});
it('"mark" characters allowed, separator "." included in input string', function () {
getSlug("foo . bar baz", {
uric: true,
separator: '.'
})
.should.eql("foo.bar.baz");
});
});

@@ -36,4 +36,4 @@ var getSlug = require('../lib');

it('should remove trailing separator "*"', function () {
getSlug('C\'est un beau titre qui ne laisse rien à désirer !', {separator: '*'})
.should.eql('c\'est*un*beau*titre*qui*ne*laisse*rien*a*desirer*!');
getSlug(' C\'est un beau titre qui ne laisse rien à désirer !', {separator: '*'})
.should.eql('cest*un*beau*titre*qui*ne*laisse*rien*a*desirer');
});

@@ -40,0 +40,0 @@

@@ -6,8 +6,8 @@ var getSlug = require('../lib');

it('should maintain case characters, with smart trim', function () {
getSlug('Foobarbaz, Bar Baz', {smartTrim: 12}).should.eql('foobarbaz');
getSlug('Foobarbaz, Bar Baz', {smartTrim: 15}).should.eql('foobarbaz-bar');
getSlug(' Foobarbaz, Bar Baz', {smartTrim: 15}).should.eql('foobarbaz-bar');
getSlug(' Foobarbaz, Bar Baz', {smartTrim: 15}).should.eql('foobarbaz-bar');
getSlug('Foobarbaz, Bar Baz', {truncate: 12}).should.eql('foobarbaz');
getSlug('Foobarbaz, Bar Baz', {truncate: 15}).should.eql('foobarbaz-bar');
getSlug(' Foobarbaz, Bar Baz', {truncate: 15}).should.eql('foobarbaz-bar');
getSlug(' Foobarbaz, Bar Baz', {truncate: 15}).should.eql('foobarbaz-bar');
});
});
var getSlug = require('../lib');
describe('getSlug misc', function () {
describe('getSlug config combinations', function () {
it('should separate with configured character, with non-Base64 separator', function () {
getSlug('Foo, Bar Baz', {separator: '*', maintainCase: false}).should.eql('foo,*bar*baz');
getSlug('Foo, Bar Baz', {separator: '*', maintainCase: false}).should.eql('foo*bar*baz');
getSlug('Foo- Bar Baz', {separator: '*', maintainCase: false}).should.eql('foo-*bar*baz');

@@ -16,13 +16,7 @@ getSlug('Foo] Bar Baz', {separator: '*', maintainCase: false}).should.eql('foo*bar*baz');

it('should separate with configured character, with RFC3986 characters allowed', function () {
getSlug('Foo, Bar Baz', {separator: '_', rfc3986: true}).should.eql('foo,_bar_baz');
getSlug('Foo- Bar Baz', {separator: '_', rfc3986: true}).should.eql('foo-_bar_baz');
getSlug('Foo] Bar Baz', {separator: '_', rfc3986: true}).should.eql('foo_bar_baz');
});
it('should separate with configured character, with smart trim', function () {
getSlug('Foobarbaz, Bar Baz', {separator: '_', smartTrim: 12}).should.eql('foobarbaz');
getSlug('Foobarbaz, Bar Baz', {separator: '_', smartTrim: 15}).should.eql('foobarbaz_bar');
getSlug(' Foobarbaz, Bar Baz', {separator: '_', smartTrim: 15}).should.eql('foobarbaz_bar');
getSlug(' Foobarbaz, Bar Baz', {separator: '_', smartTrim: 15}).should.eql('foobarbaz_bar');
getSlug('Foobarbaz, Bar Baz', {separator: '_', truncate: 12}).should.eql('foobarbaz');
getSlug('Foobarbaz, Bar Baz', {separator: '_', truncate: 15}).should.eql('foobarbaz_bar');
getSlug(' Foobarbaz, Bar Baz', {separator: '_', truncate: 15}).should.eql('foobarbaz_bar');
getSlug(' Foobarbaz, Bar Baz', {separator: '_', truncate: 15}).should.eql('foobarbaz_bar');
});

@@ -32,3 +26,3 @@

it('should maintain case characters, with non-Base64 separator', function () {
getSlug('Foo, Bar Baz', {maintainCase: true, separator: '*'}).should.eql('Foo,*Bar*Baz');
getSlug('Foo, Bar Baz', {maintainCase: true, separator: '*'}).should.eql('Foo*Bar*Baz');
getSlug('Foo- Bar Baz', {maintainCase: true, separator: '*'}).should.eql('Foo-*Bar*Baz');

@@ -44,13 +38,7 @@ getSlug('Foo] Bar Baz', {maintainCase: true, separator: '*'}).should.eql('Foo*Bar*Baz');

it('should maintain case characters, with RFC3986 characters allowed', function () {
getSlug('Foo, Bar Baz', {maintainCase: true, rfc3986: true}).should.eql('Foo,-Bar-Baz');
getSlug('Foo- Bar Baz', {maintainCase: true, rfc3986: true}).should.eql('Foo-Bar-Baz');
getSlug('Foo] Bar Baz', {maintainCase: true, rfc3986: true}).should.eql('Foo-Bar-Baz');
});
it('should maintain case characters, with smart trim', function () {
getSlug('Foobarbaz, Bar Baz', {maintainCase: true, smartTrim: 12}).should.eql('Foobarbaz');
getSlug('Foobarbaz, Bar Baz', {maintainCase: true, smartTrim: 15}).should.eql('Foobarbaz-Bar');
getSlug(' Foobarbaz, Bar Baz', {maintainCase: true, smartTrim: 15}).should.eql('Foobarbaz-Bar');
getSlug(' Foobarbaz, Bar Baz', {maintainCase: true, smartTrim: 15}).should.eql('Foobarbaz-Bar');
getSlug('Foobarbaz, Bar Baz', {maintainCase: true, truncate: 12}).should.eql('Foobarbaz');
getSlug('Foobarbaz, Bar Baz', {maintainCase: true, truncate: 15}).should.eql('Foobarbaz-Bar');
getSlug(' Foobarbaz, Bar Baz', {maintainCase: true, truncate: 15}).should.eql('Foobarbaz-Bar');
getSlug(' Foobarbaz, Bar Baz', {maintainCase: true, truncate: 15}).should.eql('Foobarbaz-Bar');
});

@@ -66,12 +54,1 @@

});
// {
// separator: '-',
// maintainCase: false,
// onlyBase64: true, // => RFC 3986 == false
// rfc3986: false, // set 'onlyBase64' or 'rfc3986', onlyBase64 is prioritized
// smartTrim: 0 // 0 == don't trim, otherwise trim to max length,
// consider word boundaries
// }
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc