Skip to content

Instantly share code, notes, and snippets.

@Omranic
Forked from demoive/slugify.js
Last active February 26, 2019 13:07
Show Gist options
  • Select an option

  • Save Omranic/c53be563645974884ca8 to your computer and use it in GitHub Desktop.

Select an option

Save Omranic/c53be563645974884ca8 to your computer and use it in GitHub Desktop.

Revisions

  1. Omranic revised this gist Jun 21, 2017. 1 changed file with 11 additions and 0 deletions.
    11 changes: 11 additions & 0 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -656,6 +656,17 @@ if (!String.prototype.slugify) {
    'ى': 'y',
    'ي': 'y',
    'ة': 't',

    '١': '1',
    '٢': '2',
    '٣': '3',
    '٤': '4',
    '٥': '5',
    '٦': '6',
    '٧': '7',
    '٨': '8',
    '٩': '9',
    '٠': '0',

    // currency
    /*
  2. Omranic revised this gist May 14, 2015. 1 changed file with 36 additions and 1 deletion.
    37 changes: 36 additions & 1 deletion slugify.js
    Original file line number Diff line number Diff line change
    @@ -622,7 +622,42 @@ if (!String.prototype.slugify) {
    'ѭ': 'yu',
    'ѩ': 'ya',

    // currency
    // Arabic
    'ا': 'a',
    'أ': 'a',
    'إ': 'a',
    'آ': 'a',
    'ب': 'b',
    'ت': 't',
    'ث': 'th',
    'ج': 'j',
    'ح': 'h',
    'خ': 'kh',
    'د': 'd',
    'ذ': 'dh',
    'ر': 'r',
    'ز': 'z',
    'س': 's',
    'ش': 'sh',
    'ص': 's',
    'ض': 'd',
    'ط': 't',
    'ظ': 'z',
    'ع': 'a',
    'غ': 'gh',
    'ف': 'f',
    'ق': 'q',
    'ك': 'k',
    'ل': 'l',
    'م': 'm',
    'ن': 'n',
    'ه': 'h',
    'و': 'w',
    'ى': 'y',
    'ي': 'y',
    'ة': 't',

    // currency
    /*
    '₳': 'ARA',
    '฿': 'THB',
  3. @demoive demoive revised this gist Jan 27, 2013. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -644,6 +644,7 @@ if (!String.prototype.slugify) {
    '₧': 'ESP',
    '₱': 'PhP',
    '£': 'GBP',
    '₤': 'GBP',
    '₨': 'Rs',
    '₪': 'NS',
    '₮': 'MNT',
  4. @demoive demoive revised this gist Jan 26, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@
    */
    if (!String.prototype.slugify) {
    String.prototype.slugify = function (delimiter, separators) {
    var i, seps = separators && separators.length,
    var i = separators && separators.length,
    slug = this,
    delimiter = delimiter || '-',
    regexEscape = new RegExp(/[[\/\\^$*+?.()|{}\]]/g),
    @@ -692,7 +692,7 @@ if (!String.prototype.slugify) {

    // add any user-defined separator elements
    if (separators) {
    for (i = 0; i < seps; ++i) {
    for (i; i >= 0; --i) {
    sanitizer[separators[i]] = delimiter;
    }
    }
  5. @demoive demoive revised this gist Jan 26, 2013. 1 changed file with 0 additions and 90 deletions.
    90 changes: 0 additions & 90 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -706,93 +706,3 @@ if (!String.prototype.slugify) {
    return slug;
    }
    }

    str = " Mess'd up --text-- jus\"t (to) 'stress' /test/ \"this & that\" Of ?oůr! `little` \\clean\\ url fun.ction!?--> -- ";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Perché l'erba è verde?";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "'Peux-tu m'aider s'il te plaît?'";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Tänk efter nu – förr'n vi föser dig bort ";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "You+can|use/spaces\\for/the delimiter";
    console.log(str);
    console.log('"'+str.slugify(' ')+'"');
    console.log('');

    str = "Custom separator`and delimiter*example";
    console.log(str);
    console.log('"'+str.slugify('_', ['*', '`'])+'"');
    console.log('');

    str = "A_MiXeD-separator + delimiter/example";
    console.log(str);
    console.log('"'+str.slugify(' ')+'"');
    console.log('');

    str = "A_MiXeD-separator + delimiter/example";
    console.log(str);
    console.log('"'+str.slugify(' ', ['_', '-'])+'"');
    console.log('');

    str = "аз буки веди";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "рцы слово твердо";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "цы червь ша ер ять ю";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "объезд";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "подсказка-для-зимнего-отдыха";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "ΧΕΙΜΕΡΙΝΌΣ, θαλασσινή";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Δωματίου, ΎΨΟΣ, φιλοξενία.";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "ευήλιος, αύρα, ζέστη";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Now any RegEx-sensative.char (\\ ^ $ * + ? . ( ) | { } [ ]) can be used safely as the delimiter... like let's say, a period:";
    console.log(str);
    console.log('"'+str.slugify('.')+'"');
    console.log('');

    str = "Craziness: not sure^how this will work.";
    console.log(str);
    console.log('"'+str.slugify('^:')+'"');
    console.log('');
  6. @demoive demoive revised this gist Jan 26, 2013. 1 changed file with 97 additions and 4 deletions.
    101 changes: 97 additions & 4 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,8 @@
    */
    if (!String.prototype.slugify) {
    String.prototype.slugify = function (delimiter, separators) {
    var slug = this,
    var i, seps = separators && separators.length,
    slug = this,
    delimiter = delimiter || '-',
    regexEscape = new RegExp(/[[\/\\^$*+?.()|{}\]]/g),
    regexDelimiter = delimiter.replace(regexEscape, "\\$&"),
    @@ -690,9 +691,11 @@ if (!String.prototype.slugify) {
    };

    // add any user-defined separator elements
    separators && separators.forEach && separators.forEach(function (sep) {
    sanitizer[sep] = delimiter;
    });
    if (separators) {
    for (i = 0; i < seps; ++i) {
    sanitizer[separators[i]] = delimiter;
    }
    }

    // do all the replacements
    slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the prohibited filter
    @@ -703,3 +706,93 @@ if (!String.prototype.slugify) {
    return slug;
    }
    }

    str = " Mess'd up --text-- jus\"t (to) 'stress' /test/ \"this & that\" Of ?oůr! `little` \\clean\\ url fun.ction!?--> -- ";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Perché l'erba è verde?";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "'Peux-tu m'aider s'il te plaît?'";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Tänk efter nu – förr'n vi föser dig bort ";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "You+can|use/spaces\\for/the delimiter";
    console.log(str);
    console.log('"'+str.slugify(' ')+'"');
    console.log('');

    str = "Custom separator`and delimiter*example";
    console.log(str);
    console.log('"'+str.slugify('_', ['*', '`'])+'"');
    console.log('');

    str = "A_MiXeD-separator + delimiter/example";
    console.log(str);
    console.log('"'+str.slugify(' ')+'"');
    console.log('');

    str = "A_MiXeD-separator + delimiter/example";
    console.log(str);
    console.log('"'+str.slugify(' ', ['_', '-'])+'"');
    console.log('');

    str = "аз буки веди";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "рцы слово твердо";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "цы червь ша ер ять ю";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "объезд";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "подсказка-для-зимнего-отдыха";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "ΧΕΙΜΕΡΙΝΌΣ, θαλασσινή";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Δωματίου, ΎΨΟΣ, φιλοξενία.";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "ευήλιος, αύρα, ζέστη";
    console.log(str);
    console.log('"'+str.slugify()+'"');
    console.log('');

    str = "Now any RegEx-sensative.char (\\ ^ $ * + ? . ( ) | { } [ ]) can be used safely as the delimiter... like let's say, a period:";
    console.log(str);
    console.log('"'+str.slugify('.')+'"');
    console.log('');

    str = "Craziness: not sure^how this will work.";
    console.log(str);
    console.log('"'+str.slugify('^:')+'"');
    console.log('');
  7. @demoive demoive revised this gist Dec 14, 2012. 1 changed file with 132 additions and 0 deletions.
    132 changes: 132 additions & 0 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -441,6 +441,138 @@ if (!String.prototype.slugify) {
    'ψ': 'ps',
    'ω': 'o',

    // greek diacritics
    'ᾳ': 'a',
    'ά': 'a',
    'ὰ': 'a',
    'ᾴ': 'a',
    'ᾲ': 'a',
    'ᾶ': 'a',
    'ᾷ': 'a',
    'ἀ': 'a',
    'ᾀ': 'a',
    'ἄ': 'a',
    'ᾄ': 'a',
    'ἂ': 'a',
    'ᾂ': 'a',
    'ἆ': 'a',
    'ᾆ': 'a',
    'ἁ': 'a',
    'ᾁ': 'a',
    'ἅ': 'a',
    'ᾅ': 'a',
    'ἃ': 'a',
    'ᾃ': 'a',
    'ἇ': 'a',
    'ᾇ': 'a',
    'ᾱ': 'a',
    'ᾰ': 'a',

    'έ': 'e',
    'ὲ': 'e',
    'ἐ': 'e',
    'ἔ': 'e',
    'ἒ': 'e',
    'ἑ': 'e',
    'ἕ': 'e',
    'ἓ': 'e',

    'ῃ': 'i',
    'ή': 'i',
    'ὴ': 'i',
    'ῄ': 'i',
    'ῂ': 'i',
    'ῆ': 'i',
    'ῇ': 'i',
    'ἠ': 'i',
    'ᾐ': 'i',
    'ἤ': 'i',
    'ᾔ': 'i',
    'ἢ': 'i',
    'ᾒ': 'i',
    'ἦ': 'i',
    'ᾖ': 'i',
    'ἡ': 'i',
    'ᾑ': 'i',
    'ἥ': 'i',
    'ᾕ': 'i',
    'ἣ': 'i',
    'ᾓ': 'i',
    'ἧ': 'i',
    'ᾗ': 'i',

    'ί': 'i',
    'ὶ': 'i',
    'ῖ': 'i',
    'ἰ': 'i',
    'ἴ': 'i',
    'ἲ': 'i',
    'ἶ': 'i',
    'ἱ': 'i',
    'ἵ': 'i',
    'ἳ': 'i',
    'ἷ': 'i',
    'ϊ': 'i',
    'ΐ': 'i',
    'ῒ': 'i',
    'ῗ': 'i',
    'ῑ': 'i',
    'ῐ': 'i',

    'ό': 'o',
    'ὸ': 'o',
    'ὀ': 'o',
    'ὄ': 'o',
    'ὂ': 'o',
    'ὁ': 'o',
    'ὅ': 'o',
    'ὃ': 'o',

    'ύ': 'u',
    'ὺ': 'u',
    'ῦ': 'u',
    'ὐ': 'u',
    'ὔ': 'u',
    'ὒ': 'u',
    'ὖ': 'u',
    'ὑ': 'u',
    'ὕ': 'u',
    'ὓ': 'u',
    'ὗ': 'u',
    'ϋ': 'u',
    'ΰ': 'u',
    'ῢ': 'u',
    'ῧ': 'u',
    'ῡ': 'u',
    'ῠ': 'u',

    'ῳ': 'o',
    'ώ': 'o',
    'ῴ': 'o',
    'ὼ': 'o',
    'ῲ': 'o',
    'ῶ': 'o',
    'ῷ': 'o',
    'ὠ': 'o',
    'ᾠ': 'o',
    'ὤ': 'o',
    'ᾤ': 'o',
    'ὢ': 'o',
    'ᾢ': 'o',
    'ὦ': 'o',
    'ᾦ': 'o',
    'ὡ': 'o',
    'ᾡ': 'o',
    'ὥ': 'o',
    'ᾥ': 'o',
    'ὣ': 'o',
    'ᾣ': 'o',
    'ὧ': 'o',
    'ᾧ': 'o',

    'ῤ': 'r',
    'ῥ': 'r',

    // cyrillic (russian)
    'а': 'a',
    'б': 'b',
  8. @demoive demoive revised this gist Dec 13, 2012. 1 changed file with 25 additions and 4 deletions.
    29 changes: 25 additions & 4 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -11,9 +11,11 @@ if (!String.prototype.slugify) {
    String.prototype.slugify = function (delimiter, separators) {
    var slug = this,
    delimiter = delimiter || '-',
    prohibited = new RegExp("([^a-z0-9" + delimiter + "])", "g"),
    consecutive = new RegExp("(" + delimiter + "+)", "g"),
    trim = new RegExp("^" + delimiter + "*(.*?)" + delimiter + "*$"),
    regexEscape = new RegExp(/[[\/\\^$*+?.()|{}\]]/g),
    regexDelimiter = delimiter.replace(regexEscape, "\\$&"),
    prohibited = new RegExp("([^a-z0-9" + regexDelimiter + "])", "g"),
    consecutive = new RegExp("(" + regexDelimiter + "+)", "g"),
    trim = new RegExp("^" + regexDelimiter + "*(.*?)" + regexDelimiter + "*$"),
    sanitizer = {
    // common latin
    'á': 'a',
    @@ -516,6 +518,25 @@ if (!String.prototype.slugify) {
    '¥': 'YEN',
    '៛': 'KHR',
    //*/

    // fractions
    /*
    '⅛': '',
    '⅙': '',
    '⅕': '',
    '¼': '',
    '⅓': '',
    '⅜': '',
    '⅖': '',
    '½': '',
    '⅗': '',
    '⅝': '',
    '⅔': '',
    '¾': '',
    '⅘': '',
    '⅚': '',
    '⅞': '',
    //*/

    // separators
    '–': delimiter,
    @@ -549,4 +570,4 @@ if (!String.prototype.slugify) {

    return slug;
    }
    }
    }
  9. @demoive demoive revised this gist Dec 12, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion slugify.js
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@
    * @param {string} Delimiter used. If not specified, defaults to a dash "-"
    * @param {array} Adds to the list of non-alphanumeric characters which
    * will be converted to the delimiter. The default list includes:
    * ['–', '—', '―', '\\', '/', '|', '+', '\'', '‘', '’', ' ']
    * ['–', '—', '―', '~', '\\', '/', '|', '+', '\'', '‘', '’', ' ']
    */
    if (!String.prototype.slugify) {
    String.prototype.slugify = function (delimiter, separators) {
  10. @demoive demoive revised this gist Dec 12, 2012. 1 changed file with 86 additions and 35 deletions.
    121 changes: 86 additions & 35 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -15,25 +15,51 @@ if (!String.prototype.slugify) {
    consecutive = new RegExp("(" + delimiter + "+)", "g"),
    trim = new RegExp("^" + delimiter + "*(.*?)" + delimiter + "*$"),
    sanitizer = {
    // diacritics
    // common latin
    'á': 'a',
    'à': 'a',
    'â': 'a',
    'ä': 'a',
    'ã': 'a',
    'æ': 'ae',
    'ç': 'c',
    'é': 'e',
    'è': 'e',
    'ê': 'e',
    'ë': 'e',
    'ẽ': 'e',
    'í': 'i',
    'ì': 'i',
    'î': 'i',
    'ï': 'i',
    'ĩ': 'i',
    'ó': 'o',
    'ò': 'o',
    'ô': 'o',
    'ö': 'o',
    'õ': 'o',
    'œ': 'oe',
    'ß': 'ss',
    'ú': 'u',
    'ù': 'u',
    'û': 'u',
    'ü': 'u',
    'ũ': 'u',

    // other diacritics
    'ă': 'a',
    'ắ': 'a',
    'ằ': 'a',
    'ẵ': 'a',
    'ẳ': 'a',
    'â': 'a',
    'ấ': 'a',
    'ầ': 'a',
    'ẫ': 'a',
    'ẩ': 'a',
    'ǎ': 'a',
    'å': 'a',
    'ǻ': 'a',
    'ä': 'a',
    'ǟ': 'a',
    'ã': 'a',
    'ȧ': 'a',
    'ǡ': 'a',
    'ą': 'a',
    @@ -49,7 +75,6 @@ if (!String.prototype.slugify) {
    'ᶏ': 'a',
    'ɐ': 'a',
    'ɑ': 'a',
    'æ': 'ae',

    'ḃ': 'b',
    'ḅ': 'b',
    @@ -65,7 +90,6 @@ if (!String.prototype.slugify) {
    'ĉ': 'c',
    'č': 'c',
    'ċ': 'c',
    'ç': 'c',
    'ḉ': 'c',
    'ȼ': 'c',
    'ƈ': 'c',
    @@ -86,18 +110,13 @@ if (!String.prototype.slugify) {
    'ᶑ': 'd',
    'ȡ': 'd',
    '∂': 'd',

    'é': 'e',
    'è': 'e',

    'ĕ': 'e',
    'ê': 'e',
    'ế': 'e',
    'ề': 'e',
    'ễ': 'e',
    'ể': 'e',
    'ě': 'e',
    'ë': 'e',
    'ẽ': 'e',
    'ė': 'e',
    'ȩ': 'e',
    'ḝ': 'e',
    @@ -141,15 +160,10 @@ if (!String.prototype.slugify) {
    'ẖ': 'h',
    'ħ': 'h',
    'ⱨ': 'h',

    'í': 'i',
    'ì': 'i',

    'ĭ': 'i',
    'î': 'i',
    'ǐ': 'i',
    'ï': 'i',
    'ḯ': 'i',
    'ĩ': 'i',
    'į': 'i',
    'ī': 'i',
    'ỉ': 'i',
    @@ -222,19 +236,14 @@ if (!String.prototype.slugify) {
    'ɳ': 'n',
    'ȵ': 'n',

    'ó': 'o',
    'ò': 'o',
    'ŏ': 'o',
    'ô': 'o',
    'ố': 'o',
    'ồ': 'o',
    'ỗ': 'o',
    'ổ': 'o',
    'ǒ': 'o',
    'ö': 'o',
    'ȫ': 'o',
    'ő': 'o',
    'õ': 'o',
    'ṍ': 'o',
    'ṏ': 'o',
    'ȭ': 'o',
    @@ -261,7 +270,6 @@ if (!String.prototype.slugify) {
    'ộ': 'o',
    'ɵ': 'o',
    'ɔ': 'o',
    'œ': 'oe',

    'ṕ': 'p',
    'ṗ': 'p',
    @@ -308,7 +316,6 @@ if (!String.prototype.slugify) {
    'ʂ': 's',
    'ȿ': 's',
    'г': 's',
    'ß': 'ss',

    'ť': 't',
    'ṫ': 't',
    @@ -326,19 +333,14 @@ if (!String.prototype.slugify) {
    'ƫ': 't',
    'ȶ': 't',

    'ú': 'u',
    'ù': 'u',
    'ŭ': 'u',
    'û': 'u',
    'ǔ': 'u',
    'ů': 'u',
    'ü': 'u',
    'ǘ': 'u',
    'ǜ': 'u',
    'ǚ': 'u',
    'ǖ': 'u',
    'ű': 'u',
    'ũ': 'u',
    'ṹ': 'u',
    'ų': 'u',
    'ū': 'u',
    @@ -417,26 +419,74 @@ if (!String.prototype.slugify) {
    'ε': 'e',
    'ζ': 'z',
    'η': 'i',
    'θ': 'o',
    'θ': 'th',
    'ι': 'i',
    'κ': 'k',
    'λ': 'l',
    'μ': 'm',
    'µ': 'm',
    'ν': 'v',
    'ξ': 'xi',
    'ν': 'n',
    'ξ': 'x',
    'ο': 'o',
    'π': 'p',
    'ρ': 'r',
    'σ': 's',
    'ς': 's',
    'τ': 't',
    'υ': 'i',
    'υ': 'u', // official rule: if preceeded by 'α' OR 'ε' => 'v', by 'ο' => 'u', else => 'i'
    'φ': 'f',
    'χ': 'x',
    'χ': 'ch',
    'ψ': 'ps',
    'ω': 'o',

    // cyrillic (russian)
    'а': 'a',
    'б': 'b',
    'в': 'v',
    'г': 'g',
    'д': 'd',
    'е': 'e',
    'ё': 'e',
    'ж': 'zh',
    'з': 'z',
    'и': 'i',
    'й': 'j',
    'к': 'k',
    'л': 'l',
    'м': 'm',
    'н': 'n',
    'о': 'o',
    'п': 'p',
    'р': 'r',
    'с': 's',
    'т': 't',
    'у': 'u',
    'ф': 'f',
    'х': 'h',
    'ц': 'ts',
    'ч': 'ch',
    'ш': 'sh',
    'щ': 'sh',
    'ъ': '',
    'ы': 'i',
    'ь': '',
    'э': 'e',
    'ю': 'yu',
    'я': 'ya',
    // ---
    'і': 'j',
    'ѳ': 'f',
    'ѣ': 'e',
    'ѵ': 'i',
    'ѕ': 'z',
    'ѯ': 'ks',
    'ѱ': 'ps',
    'ѡ': 'o',
    'ѫ': 'yu',
    'ѧ': 'ya',
    'ѭ': 'yu',
    'ѩ': 'ya',

    // currency
    /*
    '₳': 'ARA',
    @@ -471,6 +521,7 @@ if (!String.prototype.slugify) {
    '–': delimiter,
    '—': delimiter,
    '―': delimiter,
    '~': delimiter,
    '/': delimiter,
    '\\': delimiter,
    '|': delimiter,
  11. @demoive demoive revised this gist Dec 10, 2012. 1 changed file with 9 additions and 5 deletions.
    14 changes: 9 additions & 5 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@ if (!String.prototype.slugify) {
    String.prototype.slugify = function (delimiter, separators) {
    var slug = this,
    delimiter = delimiter || '-',
    notAllowed = new RegExp("([^-_a-z0-9" + delimiter + "])", "g"),
    prohibited = new RegExp("([^a-z0-9" + delimiter + "])", "g"),
    consecutive = new RegExp("(" + delimiter + "+)", "g"),
    trim = new RegExp("^" + delimiter + "*(.*?)" + delimiter + "*$"),
    sanitizer = {
    @@ -466,7 +466,7 @@ if (!String.prototype.slugify) {
    '¥': 'YEN',
    '៛': 'KHR',
    //*/

    // separators
    '–': delimiter,
    '—': delimiter,
    @@ -478,7 +478,11 @@ if (!String.prototype.slugify) {
    '‘': delimiter,
    '’': delimiter,
    '\'': delimiter,
    ' ': delimiter
    ' ': delimiter,

    // permitted by default but can be overridden
    '-': '-',
    '_': '_'
    };

    // add any user-defined separator elements
    @@ -487,8 +491,8 @@ if (!String.prototype.slugify) {
    });

    // do all the replacements
    slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the notAllowed filter
    slug = slug.replace(notAllowed, function (match) { return sanitizer[match] || ''; });
    slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the prohibited filter
    slug = slug.replace(prohibited, function (match) { return sanitizer[match] || ''; });
    slug = slug.replace(consecutive, delimiter);
    slug = slug.replace(trim, "$1");

  12. @demoive demoive created this gist Dec 10, 2012.
    497 changes: 497 additions & 0 deletions slugify.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,497 @@
    /**
    * Converts a string to a "URL-safe" slug.
    * Allows for some customization with two optional parameters:
    *
    * @param {string} Delimiter used. If not specified, defaults to a dash "-"
    * @param {array} Adds to the list of non-alphanumeric characters which
    * will be converted to the delimiter. The default list includes:
    * ['–', '—', '―', '\\', '/', '|', '+', '\'', '‘', '’', ' ']
    */
    if (!String.prototype.slugify) {
    String.prototype.slugify = function (delimiter, separators) {
    var slug = this,
    delimiter = delimiter || '-',
    notAllowed = new RegExp("([^-_a-z0-9" + delimiter + "])", "g"),
    consecutive = new RegExp("(" + delimiter + "+)", "g"),
    trim = new RegExp("^" + delimiter + "*(.*?)" + delimiter + "*$"),
    sanitizer = {
    // diacritics
    'á': 'a',
    'à': 'a',
    'ă': 'a',
    'ắ': 'a',
    'ằ': 'a',
    'ẵ': 'a',
    'ẳ': 'a',
    'â': 'a',
    'ấ': 'a',
    'ầ': 'a',
    'ẫ': 'a',
    'ẩ': 'a',
    'ǎ': 'a',
    'å': 'a',
    'ǻ': 'a',
    'ä': 'a',
    'ǟ': 'a',
    'ã': 'a',
    'ȧ': 'a',
    'ǡ': 'a',
    'ą': 'a',
    'ā': 'a',
    'ả': 'a',
    'ȁ': 'a',
    'ȃ': 'a',
    'ạ': 'a',
    'ặ': 'a',
    'ậ': 'a',
    'ḁ': 'a',
    'ⱥ': 'a',
    'ᶏ': 'a',
    'ɐ': 'a',
    'ɑ': 'a',
    'æ': 'ae',

    'ḃ': 'b',
    'ḅ': 'b',
    'ḇ': 'b',
    'ƀ': 'b',
    'ɓ': 'b',
    'ƃ': 'b',
    'ᵬ': 'b',
    'ᶀ': 'b',
    'þ': 'b',

    'ć': 'c',
    'ĉ': 'c',
    'č': 'c',
    'ċ': 'c',
    'ç': 'c',
    'ḉ': 'c',
    'ȼ': 'c',
    'ƈ': 'c',
    'ɕ': 'c',

    'ď': 'd',
    'ḋ': 'd',
    'ḑ': 'd',
    'ḍ': 'd',
    'ḓ': 'd',
    'ḏ': 'd',
    'đ': 'd',
    'ɖ': 'd',
    'ɗ': 'd',
    'ƌ': 'd',
    'ᵭ': 'd',
    'ᶁ': 'd',
    'ᶑ': 'd',
    'ȡ': 'd',
    '∂': 'd',

    'é': 'e',
    'è': 'e',
    'ĕ': 'e',
    'ê': 'e',
    'ế': 'e',
    'ề': 'e',
    'ễ': 'e',
    'ể': 'e',
    'ě': 'e',
    'ë': 'e',
    'ẽ': 'e',
    'ė': 'e',
    'ȩ': 'e',
    'ḝ': 'e',
    'ę': 'e',
    'ē': 'e',
    'ḗ': 'e',
    'ḕ': 'e',
    'ẻ': 'e',
    'ȅ': 'e',
    'ȇ': 'e',
    'ẹ': 'e',
    'ệ': 'e',
    'ḙ': 'e',
    'ḛ': 'e',
    'ɇ': 'e',
    'ᶒ': 'e',

    'ḟ': 'f',
    'ƒ': 'f',
    'ᵮ': 'f',
    'ᶂ': 'f',

    'ǵ': 'g',
    'ğ': 'g',
    'ĝ': 'g',
    'ǧ': 'g',
    'ġ': 'g',
    'ģ': 'g',
    'ḡ': 'g',
    'ǥ': 'g',
    'ɠ': 'g',
    'ᶃ': 'g',

    'ĥ': 'h',
    'ȟ': 'h',
    'ḧ': 'h',
    'ḣ': 'h',
    'ḩ': 'h',
    'ḥ': 'h',
    'ḫ': 'h',
    'ẖ': 'h',
    'ħ': 'h',
    'ⱨ': 'h',

    'í': 'i',
    'ì': 'i',
    'ĭ': 'i',
    'î': 'i',
    'ǐ': 'i',
    'ï': 'i',
    'ḯ': 'i',
    'ĩ': 'i',
    'į': 'i',
    'ī': 'i',
    'ỉ': 'i',
    'ȉ': 'i',
    'ȋ': 'i',
    'ị': 'i',
    'ḭ': 'i',
    'ɨ': 'i',
    'ᵻ': 'i',
    'ᶖ': 'i',
    'i': 'i',
    'ı': 'i',

    'ĵ': 'j',
    'ɉ': 'j',
    'ǰ': 'j',
    'ȷ': 'j',
    'ʝ': 'j',
    'ɟ': 'j',
    'ʄ': 'j',

    'ḱ': 'k',
    'ǩ': 'k',
    'ķ': 'k',
    'ḳ': 'k',
    'ḵ': 'k',
    'ƙ': 'k',
    'ⱪ': 'k',
    'ᶄ': 'k',

    'ĺ': 'l',
    'ľ': 'l',
    'ļ': 'l',
    'ḷ': 'l',
    'ḹ': 'l',
    'ḽ': 'l',
    'ḻ': 'l',
    'ł': 'l',
    'ŀ': 'l',
    'ƚ': 'l',
    'ⱡ': 'l',
    'ɫ': 'l',
    'ɬ': 'l',
    'ᶅ': 'l',
    'ɭ': 'l',
    'ȴ': 'l',

    'ḿ': 'm',
    'ṁ': 'm',
    'ṃ': 'm',
    'ᵯ': 'm',
    'ᶆ': 'm',
    'ɱ': 'm',

    'ń': 'n',
    'ǹ': 'n',
    'ň': 'n',
    'ñ': 'n',
    'ṅ': 'n',
    'ņ': 'n',
    'ṇ': 'n',
    'ṋ': 'n',
    'ṉ': 'n',
    'n̈': 'n',
    'ɲ': 'n',
    'ƞ': 'n',
    'ŋ': 'n',
    'ᵰ': 'n',
    'ᶇ': 'n',
    'ɳ': 'n',
    'ȵ': 'n',

    'ó': 'o',
    'ò': 'o',
    'ŏ': 'o',
    'ô': 'o',
    'ố': 'o',
    'ồ': 'o',
    'ỗ': 'o',
    'ổ': 'o',
    'ǒ': 'o',
    'ö': 'o',
    'ȫ': 'o',
    'ő': 'o',
    'õ': 'o',
    'ṍ': 'o',
    'ṏ': 'o',
    'ȭ': 'o',
    'ȯ': 'o',
    '͘o͘': 'o',
    'ȱ': 'o',
    'ø': 'o',
    'ǿ': 'o',
    'ǫ': 'o',
    'ǭ': 'o',
    'ō': 'o',
    'ṓ': 'o',
    'ṑ': 'o',
    'ỏ': 'o',
    'ȍ': 'o',
    'ȏ': 'o',
    'ơ': 'o',
    'ớ': 'o',
    'ờ': 'o',
    'ỡ': 'o',
    'ở': 'o',
    'ợ': 'o',
    'ọ': 'o',
    'ộ': 'o',
    'ɵ': 'o',
    'ɔ': 'o',
    'œ': 'oe',

    'ṕ': 'p',
    'ṗ': 'p',
    'ᵽ': 'p',
    'ƥ': 'p',
    'p̃': 'p',
    'ᵱ': 'p',
    'ᶈ': 'p',

    'ɋ': 'q',
    'ƣ': 'q',
    'ʠ': 'q',

    'ŕ': 'r',
    'ř': 'r',
    'ṙ': 'r',
    'ŗ': 'r',
    'ȑ': 'r',
    'ȓ': 'r',
    'ṛ': 'r',
    'ṝ': 'r',
    'ṟ': 'r',
    'ɍ': 'r',
    'ɽ': 'r',
    'ᵲ': 'r',
    'ᶉ': 'r',
    'ɼ': 'r',
    'ɾ': 'r',
    'ᵳ': 'r',

    'ś': 's',
    'ṥ': 's',
    'ŝ': 's',
    'š': 's',
    'ṧ': 's',
    'ṡẛ': 's',
    'ş': 's',
    'ṣ': 's',
    'ṩ': 's',
    'ș': 's',
    's̩': 's',
    'ᵴ': 's',
    'ᶊ': 's',
    'ʂ': 's',
    'ȿ': 's',
    'г': 's',
    'ß': 'ss',

    'ť': 't',
    'ṫ': 't',
    'ţ': 't',
    'ṭ': 't',
    'ț': 't',
    'ṱ': 't',
    'ṯ': 't',
    'ŧ': 't',
    'ⱦ': 't',
    'ƭ': 't',
    'ʈ': 't',
    '̈ẗ': 't',
    'ᵵ': 't',
    'ƫ': 't',
    'ȶ': 't',

    'ú': 'u',
    'ù': 'u',
    'ŭ': 'u',
    'û': 'u',
    'ǔ': 'u',
    'ů': 'u',
    'ü': 'u',
    'ǘ': 'u',
    'ǜ': 'u',
    'ǚ': 'u',
    'ǖ': 'u',
    'ű': 'u',
    'ũ': 'u',
    'ṹ': 'u',
    'ų': 'u',
    'ū': 'u',
    'ṻ': 'u',
    'ủ': 'u',
    'ȕ': 'u',
    'ȗ': 'u',
    'ư': 'u',
    'ứ': 'u',
    'ừ': 'u',
    'ữ': 'u',
    'ử': 'u',
    'ự': 'u',
    'ụ': 'u',
    'ṳ': 'u',
    'ṷ': 'u',
    'ṵ': 'u',
    'ʉ': 'u',
    'ᵾ': 'u',
    'ᶙ': 'u',

    'ṽ': 'v',
    'ṿ': 'v',
    'ʋ': 'v',
    'ᶌ': 'v',
    'ⱴ': 'v',

    'ẃ': 'w',
    'ẁ': 'w',
    'ŵ': 'w',
    'ẅ': 'w',
    'ẇ': 'w',
    'ẉ': 'w',
    'ẘ': 'w',

    'ẍ': 'x',
    'ẋ': 'x',
    'ᶍ': 'x',

    'ý': 'y',
    'ỳ': 'y',
    'ŷ': 'y',
    'ẙ': 'y',
    'ÿ': 'y',
    'ỹ': 'y',
    'ẏ': 'y',
    'ȳ': 'y',
    'ỷ': 'y',
    'ỵ': 'y',
    'ɏ': 'y',
    'ƴ': 'y',
    'ʏ': 'y',

    'ź': 'z',
    'ẑ': 'z',
    'ž': 'z',
    'ż': 'z',
    'ẓ': 'z',
    'ẕ': 'z',
    'ƶ': 'z',
    'ȥ': 'z',
    'ⱬ': 'z',
    'ᵶ': 'z',
    'ᶎ': 'z',
    'ʐ': 'z',
    'ʑ': 'z',
    'ɀ': 'z',

    // greek
    'α': 'a',
    'β': 'b',
    'γ': 'g',
    'ɣ': 'g',
    'δ': 'd',
    'ð': 'd',
    'ε': 'e',
    'ζ': 'z',
    'η': 'i',
    'θ': 'o',
    'ι': 'i',
    'κ': 'k',
    'λ': 'l',
    'μ': 'm',
    'µ': 'm',
    'ν': 'v',
    'ξ': 'xi',
    'ο': 'o',
    'π': 'p',
    'ρ': 'r',
    'σ': 's',
    'ς': 's',
    'τ': 't',
    'υ': 'i',
    'φ': 'f',
    'χ': 'x',
    'ψ': 'ps',
    'ω': 'o',

    // currency
    /*
    '₳': 'ARA',
    '฿': 'THB',
    '₵': 'GHS',
    '¢': 'c',
    '₡': 'CRC',
    '₢': 'Cr',
    '₠': 'XEU',
    '$': 'USD',
    '₫': 'VND',
    '৳': 'BDT',
    '₯': 'GRD',
    '€': 'EUR',
    '₣': 'FRF',
    '₲': 'PYG',
    '₴': 'HRN',
    '₭': 'LAK',
    '₦': 'NGN',
    '₧': 'ESP',
    '₱': 'PhP',
    '£': 'GBP',
    '₨': 'Rs',
    '₪': 'NS',
    '₮': 'MNT',
    '₩': 'WON',
    '¥': 'YEN',
    '៛': 'KHR',
    //*/

    // separators
    '–': delimiter,
    '—': delimiter,
    '―': delimiter,
    '/': delimiter,
    '\\': delimiter,
    '|': delimiter,
    '+': delimiter,
    '‘': delimiter,
    '’': delimiter,
    '\'': delimiter,
    ' ': delimiter
    };

    // add any user-defined separator elements
    separators && separators.forEach && separators.forEach(function (sep) {
    sanitizer[sep] = delimiter;
    });

    // do all the replacements
    slug = slug.toLowerCase(); // if we don't do this, add the uppercase versions to the sanitizer plus inlcude A-Z in the notAllowed filter
    slug = slug.replace(notAllowed, function (match) { return sanitizer[match] || ''; });
    slug = slug.replace(consecutive, delimiter);
    slug = slug.replace(trim, "$1");

    return slug;
    }
    }