UNPKG

1.36 kBJavaScriptView Raw
1/**
2 * Slugger generates header id
3 */
4export class Slugger {
5 constructor() {
6 this.seen = {};
7 }
8
9 /**
10 * @param {string} value
11 */
12 serialize(value) {
13 return value
14 .toLowerCase()
15 .trim()
16 // remove html tags
17 .replace(/<[!\/a-z].*?>/ig, '')
18 // remove unwanted chars
19 .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
20 .replace(/\s/g, '-');
21 }
22
23 /**
24 * Finds the next safe (unique) slug to use
25 * @param {string} originalSlug
26 * @param {boolean} isDryRun
27 */
28 getNextSafeSlug(originalSlug, isDryRun) {
29 let slug = originalSlug;
30 let occurenceAccumulator = 0;
31 if (this.seen.hasOwnProperty(slug)) {
32 occurenceAccumulator = this.seen[originalSlug];
33 do {
34 occurenceAccumulator++;
35 slug = originalSlug + '-' + occurenceAccumulator;
36 } while (this.seen.hasOwnProperty(slug));
37 }
38 if (!isDryRun) {
39 this.seen[originalSlug] = occurenceAccumulator;
40 this.seen[slug] = 0;
41 }
42 return slug;
43 }
44
45 /**
46 * Convert string to unique id
47 * @param {object} [options]
48 * @param {boolean} [options.dryrun] Generates the next unique slug without
49 * updating the internal accumulator.
50 */
51 slug(value, options = {}) {
52 const slug = this.serialize(value);
53 return this.getNextSafeSlug(slug, options.dryrun);
54 }
55}