1module.exports = abbrev 2 3function abbrev (...args) { 4 let list = args.length === 1 || Array.isArray(args[0]) ? args[0] : args 5 6 for (let i = 0, l = list.length; i < l; i++) { 7 list[i] = typeof list[i] === 'string' ? list[i] : String(list[i]) 8 } 9 10 // sort them lexicographically, so that they're next to their nearest kin 11 list = list.sort(lexSort) 12 13 // walk through each, seeing how much it has in common with the next and previous 14 const abbrevs = {} 15 let prev = '' 16 for (let ii = 0, ll = list.length; ii < ll; ii++) { 17 const current = list[ii] 18 const next = list[ii + 1] || '' 19 let nextMatches = true 20 let prevMatches = true 21 if (current === next) { 22 continue 23 } 24 let j = 0 25 const cl = current.length 26 for (; j < cl; j++) { 27 const curChar = current.charAt(j) 28 nextMatches = nextMatches && curChar === next.charAt(j) 29 prevMatches = prevMatches && curChar === prev.charAt(j) 30 if (!nextMatches && !prevMatches) { 31 j++ 32 break 33 } 34 } 35 prev = current 36 if (j === cl) { 37 abbrevs[current] = current 38 continue 39 } 40 for (let a = current.slice(0, j); j <= cl; j++) { 41 abbrevs[a] = current 42 a += current.charAt(j) 43 } 44 } 45 return abbrevs 46} 47 48function lexSort (a, b) { 49 return a === b ? 0 : a > b ? 1 : -1 50} 51