UNPKG

12.5 kBJavaScriptView Raw
1(function (root) {
2 var base64
3 if (typeof window === 'undefined') {
4 base64 = function (input) {
5 return Buffer.from(input).toString('base64')
6 }
7 } else {
8 base64 = function (input) {
9 // eslint-disable-next-line no-undef
10 return btoa(unescape(encodeURIComponent(input)))
11 }
12 }
13
14 function slug (string, opts) {
15 var result = slugify(string, opts)
16 // If output is an empty string, try slug for base64 of string.
17 if (result === '') {
18 result = slugify(base64(string), opts)
19 }
20 return result
21 }
22
23 function slugify (string, opts) {
24 if (typeof string !== 'string') {
25 throw new Error('slug() requires a string argument')
26 }
27 if (typeof opts === 'string') { opts = { replacement: opts } }
28 opts = opts || {}
29 opts.mode = opts.mode || slug.defaults.mode
30 var defaults = slug.defaults.modes[opts.mode]
31 var keys = ['replacement', 'multicharmap', 'charmap', 'remove', 'lower']
32 for (let key, i = 0, l = keys.length; i < l; i++) {
33 key = keys[i]
34 opts[key] = (key in opts) ? opts[key] : defaults[key]
35 }
36
37 var lengths = []
38 for (const key in opts.multicharmap) {
39 if (!Object.prototype.hasOwnProperty.call(opts.multicharmap, key)) { continue }
40
41 var len = key.length
42 if (lengths.indexOf(len) === -1) { lengths.push(len) }
43 }
44
45 var result = ''
46 for (let char, i = 0, l = string.length; i < l; i++) {
47 char = string[i]
48 if (!lengths.some(function (len) {
49 var str = string.substr(i, len)
50 if (opts.multicharmap[str]) {
51 i += len - 1
52 char = opts.multicharmap[str]
53 return true
54 } else return false
55 })) {
56 if (opts.charmap[char]) {
57 char = opts.charmap[char]
58 }
59 }
60 const allowedChars = opts.mode === 'rfc3986' ? /[^\w\s\-.~]/g : /[^A-Za-z0-9\s]/g
61 // next line preserves the replacement character in case it is included in allowedChars
62 char = char.replace(opts.replacement, ' ')
63 char = char.replace(allowedChars, '') // allowed
64 if (opts.remove) char = char.replace(opts.remove, '') // add flavour
65 result += char
66 }
67 result = result.trim()
68 result = result.replace(/[-\s]+/g, opts.replacement) // convert spaces
69 result = result.replace(opts.replacement + '$', '') // remove trailing separator
70 if (opts.lower) {
71 result = result.toLowerCase()
72 }
73 return result
74 }
75
76 slug.defaults = {
77 mode: 'pretty'
78 }
79
80 const initialMulticharmap = {
81 '<3': 'love',
82 '&&': 'and',
83 '||': 'or',
84 'w/': 'with',
85 // multibyte devanagari characters (hindi, sanskrit, etc.)
86 फ़: 'Fi',
87 ग़: 'Ghi',
88 ख़: 'Khi',
89 क़: 'Qi',
90 ड़: 'ugDha',
91 ढ़: 'ugDhha',
92 य़: 'Yi',
93 ज़: 'Za'
94 }
95 slug.multicharmap = slug.defaults.multicharmap = Object.assign({}, initialMulticharmap)
96
97 // https://github.com/django/django/blob/master/django/contrib/admin/static/admin/js/urlify.js
98 const initialCharmap = {
99 // latin
100 À: 'A',
101 Á: 'A',
102 Â: 'A',
103 Ã: 'A',
104 Ä: 'A',
105 Å: 'A',
106 Æ: 'AE',
107 Ç: 'C',
108 È: 'E',
109 É: 'E',
110 Ê: 'E',
111 Ë: 'E',
112 Ì: 'I',
113 Í: 'I',
114 Î: 'I',
115 Ï: 'I',
116 Ð: 'D',
117 Ñ: 'N',
118 Ò: 'O',
119 Ó: 'O',
120 Ô: 'O',
121 Õ: 'O',
122 Ö: 'O',
123 Ő: 'O',
124 Ø: 'O',
125 Ù: 'U',
126 Ú: 'U',
127 Û: 'U',
128 Ü: 'U',
129 Ű: 'U',
130 Ý: 'Y',
131 Þ: 'TH',
132 ß: 'ss',
133 à: 'a',
134 á: 'a',
135 â: 'a',
136 ã: 'a',
137 ä: 'a',
138 å: 'a',
139 æ: 'ae',
140 ç: 'c',
141 è: 'e',
142 é: 'e',
143 ê: 'e',
144 ë: 'e',
145 ì: 'i',
146 í: 'i',
147 î: 'i',
148 ï: 'i',
149 ð: 'd',
150 ñ: 'n',
151 ò: 'o',
152 ó: 'o',
153 ô: 'o',
154 õ: 'o',
155 ö: 'o',
156 ő: 'o',
157 ø: 'o',
158 ù: 'u',
159 ú: 'u',
160 û: 'u',
161 ü: 'u',
162 ű: 'u',
163 ý: 'y',
164 þ: 'th',
165 ÿ: 'y',
166 ẞ: 'SS',
167 // greek
168 α: 'a',
169 β: 'b',
170 γ: 'g',
171 δ: 'd',
172 ε: 'e',
173 ζ: 'z',
174 η: 'h',
175 θ: '8',
176 ι: 'i',
177 κ: 'k',
178 λ: 'l',
179 μ: 'm',
180 ν: 'n',
181 ξ: '3',
182 ο: 'o',
183 π: 'p',
184 ρ: 'r',
185 σ: 's',
186 τ: 't',
187 υ: 'y',
188 φ: 'f',
189 χ: 'x',
190 ψ: 'ps',
191 ω: 'w',
192 ά: 'a',
193 έ: 'e',
194 ί: 'i',
195 ό: 'o',
196 ύ: 'y',
197 ή: 'h',
198 ώ: 'w',
199 ς: 's',
200 ϊ: 'i',
201 ΰ: 'y',
202 ϋ: 'y',
203 ΐ: 'i',
204 Α: 'A',
205 Β: 'B',
206 Γ: 'G',
207 Δ: 'D',
208 Ε: 'E',
209 Ζ: 'Z',
210 Η: 'H',
211 Θ: '8',
212 Ι: 'I',
213 Κ: 'K',
214 Λ: 'L',
215 Μ: 'M',
216 Ν: 'N',
217 Ξ: '3',
218 Ο: 'O',
219 Π: 'P',
220 Ρ: 'R',
221 Σ: 'S',
222 Τ: 'T',
223 Υ: 'Y',
224 Φ: 'F',
225 Χ: 'X',
226 Ψ: 'PS',
227 Ω: 'W',
228 Ά: 'A',
229 Έ: 'E',
230 Ί: 'I',
231 Ό: 'O',
232 Ύ: 'Y',
233 Ή: 'H',
234 Ώ: 'W',
235 Ϊ: 'I',
236 Ϋ: 'Y',
237 // turkish
238 ş: 's',
239 Ş: 'S',
240 ı: 'i',
241 İ: 'I',
242 ğ: 'g',
243 Ğ: 'G',
244 // russian
245 а: 'a',
246 б: 'b',
247 в: 'v',
248 г: 'g',
249 д: 'd',
250 е: 'e',
251 ё: 'yo',
252 ж: 'zh',
253 з: 'z',
254 и: 'i',
255 й: 'j',
256 к: 'k',
257 л: 'l',
258 м: 'm',
259 н: 'n',
260 о: 'o',
261 п: 'p',
262 р: 'r',
263 с: 's',
264 т: 't',
265 у: 'u',
266 ф: 'f',
267 х: 'h',
268 ц: 'c',
269 ч: 'ch',
270 ш: 'sh',
271 щ: 'sh',
272 ъ: 'u',
273 ы: 'y',
274 ь: '',
275 э: 'e',
276 ю: 'yu',
277 я: 'ya',
278 А: 'A',
279 Б: 'B',
280 В: 'V',
281 Г: 'G',
282 Д: 'D',
283 Е: 'E',
284 Ё: 'Yo',
285 Ж: 'Zh',
286 З: 'Z',
287 И: 'I',
288 Й: 'J',
289 К: 'K',
290 Л: 'L',
291 М: 'M',
292 Н: 'N',
293 О: 'O',
294 П: 'P',
295 Р: 'R',
296 С: 'S',
297 Т: 'T',
298 У: 'U',
299 Ф: 'F',
300 Х: 'H',
301 Ц: 'C',
302 Ч: 'Ch',
303 Ш: 'Sh',
304 Щ: 'Sh',
305 Ъ: 'U',
306 Ы: 'Y',
307 Ь: '',
308 Э: 'E',
309 Ю: 'Yu',
310 Я: 'Ya',
311 // ukranian
312 Є: 'Ye',
313 І: 'I',
314 Ї: 'Yi',
315 Ґ: 'G',
316 є: 'ye',
317 і: 'i',
318 ї: 'yi',
319 ґ: 'g',
320 // czech
321 č: 'c',
322 ď: 'd',
323 ě: 'e',
324 ň: 'n',
325 ř: 'r',
326 š: 's',
327 ť: 't',
328 ů: 'u',
329 ž: 'z',
330 Č: 'C',
331 Ď: 'D',
332 Ě: 'E',
333 Ň: 'N',
334 Ř: 'R',
335 Š: 'S',
336 Ť: 'T',
337 Ů: 'U',
338 Ž: 'Z',
339 // polish
340 ą: 'a',
341 ć: 'c',
342 ę: 'e',
343 ł: 'l',
344 ń: 'n',
345 ś: 's',
346 ź: 'z',
347 ż: 'z',
348 Ą: 'A',
349 Ć: 'C',
350 Ę: 'E',
351 Ł: 'L',
352 Ń: 'N',
353 Ś: 'S',
354 Ź: 'Z',
355 Ż: 'Z',
356 // latvian
357 ā: 'a',
358 ē: 'e',
359 ģ: 'g',
360 ī: 'i',
361 ķ: 'k',
362 ļ: 'l',
363 ņ: 'n',
364 ū: 'u',
365 Ā: 'A',
366 Ē: 'E',
367 Ģ: 'G',
368 Ī: 'I',
369 Ķ: 'K',
370 Ļ: 'L',
371 Ņ: 'N',
372 Ū: 'U',
373 // arabic
374 أ: 'a',
375 ب: 'b',
376 ت: 't',
377 ث: 'th',
378 ج: 'g',
379 ح: 'h',
380 خ: 'kh',
381 د: 'd',
382 ذ: 'th',
383 ر: 'r',
384 ز: 'z',
385 س: 's',
386 ش: 'sh',
387 ص: 's',
388 ض: 'd',
389 ط: 't',
390 ظ: 'th',
391 ع: 'aa',
392 غ: 'gh',
393 ف: 'f',
394 ق: 'k',
395 ك: 'k',
396 ل: 'l',
397 م: 'm',
398 ن: 'n',
399 ه: 'h',
400 و: 'o',
401 ي: 'y',
402 // farsi
403 آ: 'a',
404 ا: 'a',
405 پ: 'p',
406 ژ: 'zh',
407 گ: 'g',
408 چ: 'ch',
409 ک: 'k',
410 ی: 'i',
411 // lithuanian
412 ė: 'e',
413 į: 'i',
414 ų: 'u',
415 Ė: 'E',
416 Į: 'I',
417 Ų: 'U',
418 // romanian
419 ț: 't',
420 Ț: 'T',
421 ţ: 't',
422 Ţ: 'T',
423 ș: 's',
424 Ș: 'S',
425 ă: 'a',
426 Ă: 'A',
427 // vietnamese
428 Ạ: 'A',
429 Ả: 'A',
430 Ầ: 'A',
431 Ấ: 'A',
432 Ậ: 'A',
433 Ẩ: 'A',
434 Ẫ: 'A',
435 Ằ: 'A',
436 Ắ: 'A',
437 Ặ: 'A',
438 Ẳ: 'A',
439 Ẵ: 'A',
440 Ẹ: 'E',
441 Ẻ: 'E',
442 Ẽ: 'E',
443 Ề: 'E',
444 Ế: 'E',
445 Ệ: 'E',
446 Ể: 'E',
447 Ễ: 'E',
448 Ị: 'I',
449 Ỉ: 'I',
450 Ĩ: 'I',
451 Ọ: 'O',
452 Ỏ: 'O',
453 Ồ: 'O',
454 Ố: 'O',
455 Ộ: 'O',
456 Ổ: 'O',
457 Ỗ: 'O',
458 Ơ: 'O',
459 Ờ: 'O',
460 Ớ: 'O',
461 Ợ: 'O',
462 Ở: 'O',
463 Ỡ: 'O',
464 Ụ: 'U',
465 Ủ: 'U',
466 Ũ: 'U',
467 Ư: 'U',
468 Ừ: 'U',
469 Ứ: 'U',
470 Ự: 'U',
471 Ử: 'U',
472 Ữ: 'U',
473 Ỳ: 'Y',
474 Ỵ: 'Y',
475 Ỷ: 'Y',
476 Ỹ: 'Y',
477 Đ: 'D',
478 ạ: 'a',
479 ả: 'a',
480 ầ: 'a',
481 ấ: 'a',
482 ậ: 'a',
483 ẩ: 'a',
484 ẫ: 'a',
485 ằ: 'a',
486 ắ: 'a',
487 ặ: 'a',
488 ẳ: 'a',
489 ẵ: 'a',
490 ẹ: 'e',
491 ẻ: 'e',
492 ẽ: 'e',
493 ề: 'e',
494 ế: 'e',
495 ệ: 'e',
496 ể: 'e',
497 ễ: 'e',
498 ị: 'i',
499 ỉ: 'i',
500 ĩ: 'i',
501 ọ: 'o',
502 ỏ: 'o',
503 ồ: 'o',
504 ố: 'o',
505 ộ: 'o',
506 ổ: 'o',
507 ỗ: 'o',
508 ơ: 'o',
509 ờ: 'o',
510 ớ: 'o',
511 ợ: 'o',
512 ở: 'o',
513 ỡ: 'o',
514 ụ: 'u',
515 ủ: 'u',
516 ũ: 'u',
517 ư: 'u',
518 ừ: 'u',
519 ứ: 'u',
520 ự: 'u',
521 ử: 'u',
522 ữ: 'u',
523 ỳ: 'y',
524 ỵ: 'y',
525 ỷ: 'y',
526 ỹ: 'y',
527 đ: 'd',
528 // kazakh
529 Ә: 'AE',
530 ә: 'ae',
531 Ғ: 'GH',
532 ғ: 'gh',
533 Қ: 'KH',
534 қ: 'kh',
535 Ң: 'NG',
536 ң: 'ng',
537 Ү: 'UE',
538 ү: 'ue',
539 Ұ: 'U',
540 ұ: 'u',
541 Һ: 'H',
542 һ: 'h',
543 Ө: 'OE',
544 ө: 'oe',
545 // serbian
546 ђ: 'dj',
547 ј: 'j',
548 љ: 'lj',
549 њ: 'nj',
550 ћ: 'c',
551 џ: 'dz',
552 Ђ: 'Dj',
553 Ј: 'j',
554 Љ: 'Lj',
555 Њ: 'Nj',
556 Ћ: 'C',
557 Џ: 'Dz',
558 nj: 'nj',
559 lj: 'lj',
560 Nj: 'NJ',
561 Lj: 'LJ',
562 // hindi
563 अ: 'a',
564 आ: 'aa',
565 ए: 'e',
566 ई: 'ii',
567 ऍ: 'ei',
568 ऎ: 'ae',
569 ऐ: 'ai',
570 इ: 'i',
571 ओ: 'o',
572 ऑ: 'oi',
573 ऒ: 'oii',
574 ऊ: 'uu',
575 औ: 'ou',
576 उ: 'u',
577 ब: 'B',
578 भ: 'Bha',
579 च: 'Ca',
580 छ: 'Chha',
581 ड: 'Da',
582 ढ: 'Dha',
583 फ: 'Fa',
584 ग: 'Ga',
585 घ: 'Gha',
586 ग़: 'Ghi',
587 ह: 'Ha',
588 ज: 'Ja',
589 झ: 'Jha',
590 क: 'Ka',
591 ख: 'Kha',
592 ख़: 'Khi',
593 ल: 'L',
594 ळ: 'Li',
595 ऌ: 'Li',
596 ऴ: 'Lii',
597 ॡ: 'Lii',
598 म: 'Ma',
599 न: 'Na',
600 ङ: 'Na',
601 ञ: 'Nia',
602 ण: 'Nae',
603 ऩ: 'Ni',
604 ॐ: 'oms',
605 प: 'Pa',
606 क़: 'Qi',
607 र: 'Ra',
608 ऋ: 'Ri',
609 ॠ: 'Ri',
610 ऱ: 'Ri',
611 स: 'Sa',
612 श: 'Sha',
613 ष: 'Shha',
614 ट: 'Ta',
615 त: 'Ta',
616 ठ: 'Tha',
617 द: 'Tha',
618 थ: 'Tha',
619 ध: 'Thha',
620 ड़: 'ugDha',
621 ढ़: 'ugDhha',
622 व: 'Va',
623 य: 'Ya',
624 य़: 'Yi',
625 ज़: 'Za',
626 // currency
627 '€': 'euro',
628 '₢': 'cruzeiro',
629 '₣': 'french franc',
630 '£': 'pound',
631 '₤': 'lira',
632 '₥': 'mill',
633 '₦': 'naira',
634 '₧': 'peseta',
635 '₨': 'rupee',
636 '₩': 'won',
637 '₪': 'new shequel',
638 '₫': 'dong',
639 '₭': 'kip',
640 '₮': 'tugrik',
641 '₯': 'drachma',
642 '₰': 'penny',
643 '₱': 'peso',
644 '₲': 'guarani',
645 '₳': 'austral',
646 '₴': 'hryvnia',
647 '₵': 'cedi',
648 '¢': 'cent',
649 '¥': 'yen',
650 元: 'yuan',
651 円: 'yen',
652 '﷼': 'rial',
653 '₠': 'ecu',
654 '¤': 'currency',
655 '฿': 'baht',
656 $: 'dollar',
657 '₹': 'indian rupee',
658 '₽': 'russian ruble',
659 '₿': 'bitcoin',
660 '₸': 'kazakhstani tenge',
661 // symbols
662 '©': 'c',
663 œ: 'oe',
664 Œ: 'OE',
665 '∑': 'sum',
666 '®': 'r',
667 '∂': 'd',
668 ƒ: 'f',
669 '™': 'tm',
670 '℠': 'sm',
671 '…': '...',
672 '˚': 'o',
673 º: 'o',
674 ª: 'a',
675 '∆': 'delta',
676 '∞': 'infinity',
677 '♥': 'love',
678 '&': 'and',
679 '|': 'or',
680 '<': 'less',
681 '>': 'greater'
682 }
683 slug.charmap = slug.defaults.charmap = Object.assign({}, initialCharmap)
684
685 slug.reset = function () {
686 slug.defaults.modes.rfc3986.charmap = slug.defaults.modes.pretty.charmap = slug.charmap = slug.defaults.charmap = Object.assign({}, initialCharmap)
687 slug.defaults.modes.rfc3986.multiCharmap = slug.defaults.modes.pretty.multiCharmap = slug.multicharmap = slug.defaults.multicharmap = Object.assign({}, initialMulticharmap)
688 }
689
690 slug.extend = function (customMap) {
691 Object.assign(slug.charmap, customMap)
692 }
693
694 slug.defaults.modes = {
695 rfc3986: {
696 replacement: '-',
697 remove: null,
698 lower: true,
699 charmap: slug.defaults.charmap,
700 multicharmap: slug.defaults.multicharmap
701 },
702 pretty: {
703 replacement: '-',
704 remove: /[.]/g,
705 lower: true,
706 charmap: slug.defaults.charmap,
707 multicharmap: slug.defaults.multicharmap
708 }
709 }
710
711 /* global define */
712 // Be compatible with different module systems
713
714 if (typeof define !== 'undefined' && define.amd) { // AMD
715 define([], function () { return slug })
716 } else if (typeof module !== 'undefined' && module.exports) { // CommonJS
717 module.exports = slug
718 } else { // Script tag
719 root.slug = slug
720 }
721}(this))