Comparing version 0.2.1 to 0.2.3
{ | ||
"name": "initials", | ||
"version": "0.2.1", | ||
"version": "0.2.3", | ||
"authors": [ | ||
@@ -20,3 +20,3 @@ "Gregor Martynus <gregor@martynus.net>" | ||
"devDependencies": { | ||
"bootstrap-editable-table": "~0.1.0", | ||
"bootstrap-editable-table": "~0.2.3", | ||
"qunit": "~1.14.0" | ||
@@ -23,0 +23,0 @@ }, |
124
initials.js
@@ -17,2 +17,6 @@ /* global define */ | ||
// defaults | ||
var defaultLength = 2; | ||
// regex patterns | ||
var uppercaseLettersOnlyPattern = /^[A-Z]+$/; | ||
@@ -31,6 +35,6 @@ var initialsInNamePattern = /\(([^\)]+)\)/; | ||
// | ||
function initials(nameOrNames, length) { | ||
function initials(nameOrNames, options) { | ||
if (! nameOrNames) return ''; | ||
if (typeof nameOrNames === 'string') return initialsForSingleName(nameOrNames, length); | ||
return initialsForMultipleNames(nameOrNames, length); | ||
if (typeof nameOrNames === 'string') return initialsForSingleName(nameOrNames, normalize(options)); | ||
return initialsForMultipleNames(nameOrNames, normalize(options)); | ||
} | ||
@@ -41,6 +45,6 @@ | ||
// | ||
function addInitialsTo (nameOrNames, length) { | ||
function addInitialsTo (nameOrNames, options) { | ||
if (! nameOrNames) return ''; | ||
if (typeof nameOrNames === 'string') return addInitialsToSingleName(nameOrNames, length); | ||
return addInitialsToMultipleNames(nameOrNames, length); | ||
if (typeof nameOrNames === 'string') return addInitialsToSingleName(nameOrNames, normalize(options)); | ||
return addInitialsToMultipleNames(nameOrNames, normalize(options)); | ||
} | ||
@@ -53,4 +57,4 @@ | ||
if (! nameOrNames) return {}; | ||
if (typeof nameOrNames === 'string') return parseSingleName(nameOrNames, options); | ||
return parseMultipleNames(nameOrNames, options); | ||
if (typeof nameOrNames === 'string') return parseSingleName(nameOrNames, normalize(options)); | ||
return parseMultipleNames(nameOrNames, normalize(options)); | ||
} | ||
@@ -63,3 +67,3 @@ | ||
// | ||
function initialsForSingleName(name, length) { | ||
function initialsForSingleName(name, options) { | ||
var matches; | ||
@@ -69,11 +73,10 @@ var result; | ||
var initials; | ||
length = length || 2; | ||
var length = options.length || 2; | ||
findFirstLettersPattern = new RegExp('\\w{'+length+'}'); | ||
if (! name) return ''; | ||
initials = findPreferredInitials(name); | ||
initials = findPreferredInitials(name, options); | ||
if (initials) return initials; | ||
name = cleanupName(name); | ||
if (! name) return ''; | ||
@@ -103,7 +106,7 @@ // remove diacritics, as they screw up the /\b/ pattern | ||
// First, we calculate all remaining options that we have | ||
var options = getPossibleInitialsForName(name); | ||
var possibleInitials = getPossibleInitialsForName(name); | ||
var option; | ||
// then we return the first option that has the required length | ||
while (option = options.shift()) { // jshint ignore:line | ||
while (option = possibleInitials.shift()) { // jshint ignore:line | ||
if (option.length >= length) return option; | ||
@@ -119,4 +122,3 @@ } | ||
// | ||
function initialsForMultipleNames (names, length) { | ||
length = length || 2; | ||
function initialsForMultipleNames (names, options) { | ||
var optionsForNames = []; | ||
@@ -127,10 +129,22 @@ var optionsCountForNames; | ||
var initialsForNamesMap = {}; | ||
var options; | ||
var initials; | ||
var possibleInitials; | ||
var length = options.length || 2; | ||
// get all possible initials for all names for given length | ||
names.forEach(function(name) { | ||
// normalize | ||
if (! name) name = ''; | ||
// known name? Gets same initials, stop here | ||
if (initialsForNamesMap[name]) return; | ||
initials = findPreferredInitials(name); | ||
// too short to extract initials from? Use name as initials. | ||
if (name.length < length) { | ||
initialsForNamesMap[name] = [name]; | ||
return; | ||
} | ||
// preferred initials like (JD)? Use these | ||
initials = findPreferredInitials(name, options); | ||
if (initials) { | ||
@@ -143,3 +157,3 @@ map[initials] = 1; | ||
// return all possible initials for given length | ||
options = getPossibleInitialsForName(name).filter( function(initials) { | ||
possibleInitials = getPossibleInitialsForName(name).filter( function(initials) { | ||
if (initials.length !== length) return false; | ||
@@ -151,3 +165,3 @@ if (map[initials]) duplicatesMap[initials] = 1; | ||
initialsForNamesMap[name] = options; | ||
initialsForNamesMap[name] = possibleInitials; | ||
}); | ||
@@ -157,8 +171,8 @@ | ||
for (var name in initialsForNamesMap) { | ||
options = initialsForNamesMap[name]; | ||
optionsForNames.push(options); | ||
possibleInitials = initialsForNamesMap[name]; | ||
optionsForNames.push(possibleInitials); | ||
for (var j = 0; j < options.length; j++) { | ||
if (duplicatesMap[options[j]]) { | ||
options.splice(j, 1); | ||
for (var i = 0; i < possibleInitials.length; i++) { | ||
if (duplicatesMap[possibleInitials[i]]) { | ||
possibleInitials.splice(i, 1); | ||
} | ||
@@ -170,4 +184,9 @@ } | ||
optionsCountForNames = optionsForNames.map( function(options) { return options.length; }); | ||
// if names were empty, optionsCountForNames is empty. In that case stop here | ||
if (optionsCountForNames.length === 0) return names; | ||
if (Math.min.apply(null, optionsCountForNames) === 0) { | ||
return initialsForMultipleNames(names, length + 1); | ||
options.length++; | ||
return initialsForMultipleNames(names, options); | ||
} | ||
@@ -182,4 +201,4 @@ | ||
// | ||
function addInitialsToSingleName (name, length) { | ||
var parts = parseSingleName(name, length); | ||
function addInitialsToSingleName (name, options) { | ||
var parts = parseSingleName(name, options); | ||
return format(parts); | ||
@@ -191,4 +210,4 @@ } | ||
// | ||
function addInitialsToMultipleNames (names, length) { | ||
return parseMultipleNames(names, length).map( format ); | ||
function addInitialsToMultipleNames (names, options) { | ||
return parseMultipleNames(names, options).map( format ); | ||
} | ||
@@ -205,11 +224,10 @@ | ||
// normalize options | ||
if (! options) options = {}; | ||
if (typeof options === 'number') options = {length: options}; | ||
if (! name) return {}; | ||
// are initials part of the name? | ||
initials = findPreferredInitials(name); | ||
initials = findPreferredInitials(name, options); | ||
if (initials) { | ||
// if yes, remove it from name | ||
name = name.replace(initials, ''); | ||
name = name.replace(uppercaseLettersOnlyPattern, ''); | ||
name = name.replace(initialsInNamePattern, ''); | ||
} | ||
@@ -221,3 +239,3 @@ | ||
// if no initials found yet, extract initials from name | ||
if (!initials) initials = initialsForSingleName(name, options.length); | ||
if (!initials) initials = initialsForSingleName(name, options); | ||
@@ -246,9 +264,8 @@ // is there an email in the name? | ||
// | ||
function parseMultipleNames (names) { | ||
var initialsArray = initialsForMultipleNames(names, length); | ||
function parseMultipleNames (names, options) { | ||
var initialsArray = initialsForMultipleNames(names, options); | ||
return names.map(function(name, i) { | ||
return parseSingleName(name, { | ||
initials: initialsArray[i] | ||
}); | ||
options.existing[name] = initialsArray[i]; | ||
return parseSingleName(name, options); | ||
}); | ||
@@ -297,4 +314,8 @@ } | ||
// | ||
function findPreferredInitials (name) { | ||
function findPreferredInitials (name, options) { | ||
var matches; | ||
// if prefered initials passed for current name | ||
if (options.existing[name]) return options.existing[name]; | ||
// if the name contains only upcase letters, let's take it as the initials as well | ||
@@ -348,3 +369,3 @@ if (uppercaseLettersOnlyPattern.test(name)) { | ||
options = options.sort(function(a, b) { | ||
return a.length - b.length; | ||
return a.length - b.length || options.indexOf(a) - options.indexOf(b); | ||
}); | ||
@@ -393,2 +414,17 @@ | ||
// | ||
// make sure that options is always an object, and that | ||
// * options.lenght is a number and >= defaultLength | ||
// * existing is set and an object | ||
// | ||
function normalize (options) { | ||
if (! options) options = {length: defaultLength}; | ||
if (typeof options === 'number') options = {length: options}; | ||
options.length = Math.max(options.length || 0, defaultLength); | ||
options.existing = options.existing || {}; | ||
return options; | ||
} | ||
// based on http://web.archive.org/web/20120918093154/http://lehelk.com/2011/05/06/script-to-remove-diacritics/ | ||
@@ -395,0 +431,0 @@ var diacriticsMap = [ |
{ | ||
"name": "initials", | ||
"version": "0.2.1", | ||
"version": "0.2.3", | ||
"description": "initials for names", | ||
@@ -5,0 +5,0 @@ "main": "initials.js", |
@@ -26,9 +26,9 @@ Initials. Because JD is shorter than John Doe | ||
```js | ||
console.log( initials('John Doe') ); | ||
initials('John Doe') | ||
// 'JD' | ||
console.log( initials(['John Doe', 'Robert Roe']) ); | ||
initials(['John Doe', 'Robert Roe']) | ||
// ['JD', 'RR'] | ||
// alias | ||
// alias for initials('John Doe') | ||
initials.find('John Doe') | ||
@@ -43,2 +43,8 @@ | ||
// 'John Doe (JD)' | ||
// pass existing initials for names | ||
initials(['John Doe', 'Jane Dane'], { | ||
existing: { 'John Doe': 'JD' } | ||
}) | ||
// ['JD', 'JDa'] | ||
``` | ||
@@ -45,0 +51,0 @@ |
/* global initials, test, equal, deepEqual */ | ||
test( 'initials( name )', function() { | ||
@@ -25,2 +26,3 @@ 'use strict'; | ||
deepEqual( initials(['John Doe', 'Jane Dane']), ['JDo', 'JDa'], 'guarantees unique initials: John Doe, Jane Dane ☛ JDo, JDa' ); | ||
deepEqual( initials(['John Doe (JD)', 'Jane Dane']), ['JD', 'JDa'], 'guarantees unique initials, respecting preferences: John Doe (JD), Jane Dane ☛ JDo, JDa' ); | ||
deepEqual( initials(['John Doe', 'Jane Dane', 'John Doe']), ['JDo', 'JDa', 'JDo'], 'same initials for same names: John Doe, Jane Dane, John Doe ☛ JDo, JDa, JDo' ); | ||
@@ -42,2 +44,18 @@ deepEqual( initials(['John Smith', 'Jane Smith']), ['JoS', 'JaS'], 'shortest initials possible: John Smith, Jane Smith ☛ JoS, JaS' ); | ||
test( 'initials( nameOrNames, {existing: initialsForNames} )', function() { | ||
'use strict'; | ||
equal( initials('John Doe', { | ||
existing: { | ||
'John Doe': 'JoDo' | ||
} | ||
}), 'JoDo', 'respect existing initials' ); | ||
deepEqual( initials(['John Doe', 'Jane Dane'], { | ||
existing: { | ||
'John Doe': 'JD' | ||
} | ||
}), ['JD', 'JDa'], 'respect existing initials' ); | ||
}); | ||
test( 'initials.addTo( name )', function() { | ||
@@ -49,4 +67,6 @@ 'use strict'; | ||
equal( initials.addTo('JD'), 'JD', 'JD ☛ JD' ); | ||
equal( initials.addTo('JD (JD)'), 'JD (JD)', 'JD (JD) ☛ JD (JD)' ); | ||
equal( initials.addTo('John Doe (JoDo) joe@example.com'), 'John Doe (JoDo) <joe@example.com>', 'John Doe (JoDo) joe@example.com ☛ John Doe (JoDo) <joe@example.com>' ); | ||
equal( initials.addTo('joe@example.com'), 'joe@example.com (jo)', 'joe@example.com ☛ joe@example.com (jo)' ); | ||
equal( initials.addTo('joe (j)'), 'joe (j)', 'joe (j) ☛ joe (j)' ); | ||
}); | ||
@@ -60,2 +80,18 @@ test( 'initials.addTo( namesArray )', function() { | ||
test( 'initials.addTo( nameOrNames, {existing: initialsForNames} )', function() { | ||
'use strict'; | ||
equal( initials.addTo('John Doe', { | ||
existing: { | ||
'John Doe': 'JoDo' | ||
} | ||
}), 'John Doe (JoDo)', 'respect existing initials' ); | ||
deepEqual( initials.addTo(['John Doe', 'Jane Dane'], { | ||
existing: { | ||
'John Doe': 'JD' | ||
} | ||
}), ['John Doe (JD)', 'Jane Dane (JDa)'], 'respect existing initials' ); | ||
}); | ||
test( 'initials.parse( name )', function() { | ||
@@ -74,1 +110,22 @@ 'use strict'; | ||
}); | ||
test( 'initials.parse( nameOrNames, {existing: initialsForNames} )', function() { | ||
'use strict'; | ||
deepEqual( initials.parse('John Doe', { | ||
existing: { | ||
'John Doe': 'JoDo' | ||
} | ||
}), {name: 'John Doe', initials: 'JoDo'}, 'respect existing initials for single name' ); | ||
deepEqual( initials.parse(['John Doe', 'Jane Dane'], { | ||
existing: { | ||
'John Doe': 'JD' | ||
} | ||
}), [{name: 'John Doe', initials: 'JD'}, {name: 'Jane Dane', initials: 'JDa'}], 'respect existing initials for multiple names' ); | ||
}); | ||
// test('debug', function() { | ||
// equal( initials('John Doe', 3), 'JDo', 'John Doe ☛ JDo' ); | ||
// }); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1941741
23376
95