Comparing version 0.1.3 to 0.2.0
{ | ||
"name": "slang", | ||
"description": "A collection of utility functions for strings", | ||
"version": "0.1.3", | ||
"version": "0.2.0", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "Devon Govett", |
@@ -167,4 +167,39 @@ Slang | ||
### slang.lang | ||
The default language to be used with all inflection methods. Initially set to 'en' for English. | ||
### slang.pluralize | ||
Pluralizes a string in the specified language or `slang.lang` by default | ||
inflector.pluralize('man') // 'men' | ||
inflector.pluralize('word', 'de') // non-default language | ||
### slang.singularize | ||
Singularizes a string in the specified language or `slang.lang` by default | ||
inflector.singularize('men') // 'man' | ||
inflector.singularize('word', 'de') // non-default language | ||
### slang.Language | ||
An object that describes a language's inflection rules. See source code for example usage. | ||
### slang.languages | ||
An object holding `slang.Language` objects that describe various languages. English ('en') is provided | ||
by default and you can add additional languages by adding them to `slang.languages`. Then you can set | ||
the default language to this new language by setting `slang.lang` or just use your language by passing | ||
the language code as the second argument to `slang.pluralize` or `slang.singularize`. | ||
// Create a language | ||
var german = new slang.Language(); | ||
// Now add inflection rules | ||
// ... | ||
// Add language | ||
slang.languages['de'] = german; | ||
// Set default language | ||
slang.lang = 'de'; | ||
## License | ||
slang is licensed under the MIT license. |
197
slang.js
@@ -17,3 +17,3 @@ (function() { | ||
// Set the slang version | ||
slang.version = '0.1.2'; | ||
slang.version = '0.2.0'; | ||
@@ -255,2 +255,82 @@ // String utility functions | ||
// Inflection | ||
// ---------- | ||
// Set default language for inflection methods | ||
slang.lang = 'en'; | ||
// Object to hold languages for inflection | ||
// Add slang.Language objects to this | ||
slang.languages = {}; | ||
// Define object to hold information about a language | ||
function Language() { | ||
this.plural = []; | ||
this.singular = []; | ||
this.uncountable = []; | ||
this.irregular = { | ||
plural: {}, | ||
singular: {} | ||
}; | ||
} | ||
slang.Language = Language; | ||
// Adds an array of irregular words to the language. | ||
// Provide an array of arrays containing the singular | ||
// and plural versions of the word | ||
Language.prototype.addIrregular = function(irregular) { | ||
for (var i = 0, len = irregular.length; i < len; i++) { | ||
var item = irregular[i]; | ||
this.irregular.plural[item[0]] = item[1]; | ||
this.irregular.singular[item[1]] = item[0]; | ||
} | ||
} | ||
// Inflects a word by the specified type ('singular' or 'plural') | ||
Language.prototype.inflect = function(word, type) { | ||
// Check if this word is uncountable | ||
if (~this.uncountable.indexOf(word.toLowerCase())) | ||
return word; | ||
// Check if this word is irregular | ||
var irregular = this.irregular[type][word]; | ||
if (irregular) | ||
return irregular; | ||
// Check rules until a match is found | ||
var rules = this[type]; | ||
for (var i = 0, len = rules.length; i < len; i++) { | ||
var regexp = rules[i][0]; | ||
if (regexp.test(word)) | ||
return word.replace(regexp, rules[i][1]); | ||
} | ||
return word; | ||
} | ||
// Pluralize a word in the specified language | ||
// or `slang.lang` by default | ||
slang.pluralize = function(word, lang) { | ||
lang || (lang = slang.lang); | ||
lang = slang.languages[lang]; | ||
if (!lang) | ||
return word; | ||
return lang.inflect(word, 'plural'); | ||
} | ||
// Singularize a word in the specified language | ||
// or `slang.lang` by default | ||
slang.singularize = function(word, lang) { | ||
lang || (lang = slang.lang); | ||
lang = slang.languages[lang]; | ||
if (!lang) | ||
return word; | ||
return lang.inflect(word, 'singular'); | ||
} | ||
// Adds the methods from the slang object to String.prototype | ||
@@ -260,2 +340,5 @@ slang.addToPrototype = function addToPrototype() { | ||
if (key === 'guid' || | ||
key === 'lang' || | ||
key === 'languages' || | ||
key === 'Language' || | ||
key === 'humanize' || | ||
@@ -276,3 +359,115 @@ key === 'isString' || | ||
} | ||
// English Inflector | ||
// ----------------- | ||
// Define language for English | ||
var en = slang.languages['en'] = new slang.Language(); | ||
en.plural = [ | ||
[/(todo)$/i, "$1s"], | ||
[/(matr|vert|ind)(?:ix|ex)$/i, "$1ices"], | ||
[/(octop|vir)us$/i, "$1i"], | ||
[/(alias|status)$/i, "$1es"], | ||
[/(cris|ax|test)is$/i, "$1es"], | ||
[/(s|ss|sh|ch|x|o)$/i, "$1es"], | ||
[/y$/i, "ies"], | ||
[/(o|e)y$/i, "$1ys"], | ||
[/([ti])um$/i, "$1a"], | ||
[/sis$/i, "ses"], | ||
[/(?:([^f])fe|([lr])f)$/i, "$1$2ves"], | ||
[/([^aeiouy]|qu)y$/i, "$1ies"], | ||
[/([m|l])ouse$/i, "$1ice"], | ||
[/^(ox)$/i, "$1en"], | ||
[/(quiz)$/i, "$1zes"], | ||
[/$/, "s"] | ||
]; | ||
en.singular = [ | ||
[/(bu|mis|kis)s$/i, "$1s"], | ||
[/([ti])a$/i, "$1um"], | ||
[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, "$1$2sis"], | ||
[/(^analy)ses$/i, "$1sis"], | ||
[/([^f])ves$/i, "$1fe"], | ||
[/([lr])ves$/i, "$1f"], | ||
[/([^aeiouy]|qu)ies$/i, "$1y"], | ||
[/ies$/i, "ie"], | ||
[/(x|ch|ss|sh)es$/i, "$1"], | ||
[/([m|l])ice$/i, "$1ouse"], | ||
[/(bus)es$/i, "$1"], | ||
[/(shoe)s$/i, "$1"], | ||
[/(o)es$/i, "$1"], | ||
[/(cris|ax|test)es$/i, "$1is"], | ||
[/(octop|vir)i$/i, "$1us"], | ||
[/(alias|status)es$/i, "$1"], | ||
[/^(ox)en/i, "$1"], | ||
[/(vert|ind)ices$/i, "$1ex"], | ||
[/(matr)ices$/i, "$1ix"], | ||
[/(quiz)zes$/i, "$1"], | ||
[/s$/i, ""] | ||
]; | ||
en.addIrregular([ | ||
['i', 'we'], | ||
['person', 'people'], | ||
['man', 'men'], | ||
['child', 'children'], | ||
['move', 'moves'], | ||
['she', 'they'], | ||
['he', 'they'], | ||
['myself', 'ourselves'], | ||
['yourself', 'ourselves'], | ||
['himself', 'themselves'], | ||
['herself', 'themselves'], | ||
['themself', 'themselves'], | ||
['mine', 'ours'], | ||
['hers', 'theirs'], | ||
['his', 'theirs'], | ||
['its', 'theirs'], | ||
['theirs', 'theirs'], | ||
['sex', 'sexes'], | ||
['this', 'that'] | ||
]); | ||
en.uncountable = [ | ||
'advice', | ||
'enegery', | ||
'excretion', | ||
'digestion', | ||
'cooperation', | ||
'health', | ||
'justice', | ||
'jeans', | ||
'labour', | ||
'machinery', | ||
'equipment', | ||
'information', | ||
'pollution', | ||
'sewage', | ||
'paper', | ||
'money', | ||
'species', | ||
'series', | ||
'rain', | ||
'rice', | ||
'fish', | ||
'sheep', | ||
'moose', | ||
'deer', | ||
'bison', | ||
'proceedings', | ||
'shears', | ||
'pincers', | ||
'breeches', | ||
'hijinks', | ||
'clippers', | ||
'chassis', | ||
'innings', | ||
'elk', | ||
'rhinoceros', | ||
'swine', | ||
'you', | ||
'news' | ||
]; | ||
})(); |
@@ -1,1 +0,1 @@ | ||
(function(){var a={};typeof module!="undefined"&&module.exports?module.exports=a:this.slang=a,a.version="0.1.2",a.isString=function(a){return Object.prototype.toString.call(a)==="[object String]"},a.capitalize=function(a){return a.charAt(0).toUpperCase()+a.slice(1)},a.uncapitalize=function(a){return a.charAt(0).toLowerCase()+a.slice(1)},a.capitalizeWords=function(b){return b.replace(/\w+/g,function(b){return a.capitalize(b)})},a.uncapitalizeWords=function(b){return b.replace(/\w+/g,function(b){return a.uncapitalize(b)})},a.isUpperCaseAt=function(a,b){return a.charAt(b).toUpperCase()===a.charAt(b)},a.isLowerCaseAt=function(a,b){return a.charAt(b).toLowerCase()===a.charAt(b)},a.swapcase=function(a){return a.replace(/([a-z]+)|([A-Z]+)/g,function(a,b,c){return b?a.toUpperCase():a.toLowerCase()})},a.camelize=function(a){return a.replace(/\W+(.)/g,function(a,b){return b.toUpperCase()})},a.dasherize=function(a){return a.replace(/\W+/g,"-").replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()},a.repeat=function(a,b){return b<1?"":(new Array(b+1)).join(a)},a.insert=function(a,b,c){return a.slice(0,c)+b+a.slice(c)},a.remove=function(a,b,c){return a.slice(0,b)+a.slice(c)},a.chop=function(a){return a.slice(0,-1)},a.trim=function(a){return a.trim?a.trim():a.replace(/^\s+/,"").replace(/\s+$/,"")},a.trimLeft=function(a){return a.trimLeft?a.trimLeft():a.replace(/^\s+/,"")},a.trimRight=function(a){return a.trimRight?a.trimRight():a.replace(/\s+$/,"")},a.truncate=function(a,b){var c=b&&b.limit||10,d=b&&b.omission||"...";return a.length<=c?a:a.slice(0,c)+d},a.join=function(a,b){var c=a.pop(),b=b||"and";return a.join(", ")+" "+b+" "+c},a.humanize=function(a){if(a%100>=11&&a%100<=13)return a+"th";switch(a%10){case 1:return a+"st";case 2:return a+"nd";case 3:return a+"rd"}return a+"th"},a.contains=function(a,b){return a.indexOf(b)>-1},a.startsWith=function(a,b){return a.indexOf(b)===0},a.endsWith=function(a,b){var c=a.length-b.length;return c>=0&&a.indexOf(b,c)>-1},a.isBlank=function(a){return/^\s*$/.test(a)},a.successor=function(a){var b="abcdefghijklmnopqrstuvwxyz",c=b.length,d=a,e=a.length;while(e>=0){var f=a.charAt(--e),g="",h=!1;if(isNaN(f)){index=b.indexOf(f.toLowerCase());if(index===-1)g=f,h=!0;else{var i=f===f.toUpperCase();g=b.charAt((index+1)%c),i&&(g=g.toUpperCase()),h=index+1>=c;if(h&&e===0){var j=i?"A":"a";d=j+g+d.slice(1);break}}}else{g=+f+1,g>9&&(g=0,h=!0);if(h&&e===0){d="1"+g+d.slice(1);break}}d=d.slice(0,e)+g+d.slice(e+1);if(!h)break}return d},a.guid=function(a){var b=[],c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",d=c.length,a=a||32;for(var e=0;e<a;e++)b[e]=c.charAt(Math.floor(Math.random()*d));return b.join("")},a.addToPrototype=function(){for(key in a){if(key==="guid"||key==="humanize"||key==="isString"||key==="version"||key==="addToPrototype")continue;(function(b){String.prototype[b]=function(){var c=Array.prototype.slice.call(arguments);return a[b].apply(a,[this].concat(c))}})(key)}}})() | ||
(function(){function b(){this.plural=[],this.singular=[],this.uncountable=[],this.irregular={plural:{},singular:{}}}var a={};typeof module!="undefined"&&module.exports?module.exports=a:this.slang=a,a.version="0.2.0",a.isString=function(a){return Object.prototype.toString.call(a)==="[object String]"},a.capitalize=function(a){return a.charAt(0).toUpperCase()+a.slice(1)},a.uncapitalize=function(a){return a.charAt(0).toLowerCase()+a.slice(1)},a.capitalizeWords=function(b){return b.replace(/\w+/g,function(b){return a.capitalize(b)})},a.uncapitalizeWords=function(b){return b.replace(/\w+/g,function(b){return a.uncapitalize(b)})},a.isUpperCaseAt=function(a,b){return a.charAt(b).toUpperCase()===a.charAt(b)},a.isLowerCaseAt=function(a,b){return a.charAt(b).toLowerCase()===a.charAt(b)},a.swapcase=function(a){return a.replace(/([a-z]+)|([A-Z]+)/g,function(a,b,c){return b?a.toUpperCase():a.toLowerCase()})},a.camelize=function(a){return a.replace(/\W+(.)/g,function(a,b){return b.toUpperCase()})},a.dasherize=function(a){return a.replace(/\W+/g,"-").replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()},a.repeat=function(a,b){return b<1?"":(new Array(b+1)).join(a)},a.insert=function(a,b,c){return a.slice(0,c)+b+a.slice(c)},a.remove=function(a,b,c){return a.slice(0,b)+a.slice(c)},a.chop=function(a){return a.slice(0,-1)},a.trim=function(a){return a.trim?a.trim():a.replace(/^\s+/,"").replace(/\s+$/,"")},a.trimLeft=function(a){return a.trimLeft?a.trimLeft():a.replace(/^\s+/,"")},a.trimRight=function(a){return a.trimRight?a.trimRight():a.replace(/\s+$/,"")},a.truncate=function(a,b){var c=b&&b.limit||10,d=b&&b.omission||"...";return a.length<=c?a:a.slice(0,c)+d},a.join=function(a,b){var c=a.pop(),b=b||"and";return a.join(", ")+" "+b+" "+c},a.humanize=function(a){if(a%100>=11&&a%100<=13)return a+"th";switch(a%10){case 1:return a+"st";case 2:return a+"nd";case 3:return a+"rd"}return a+"th"},a.contains=function(a,b){return a.indexOf(b)>-1},a.startsWith=function(a,b){return a.indexOf(b)===0},a.endsWith=function(a,b){var c=a.length-b.length;return c>=0&&a.indexOf(b,c)>-1},a.isBlank=function(a){return/^\s*$/.test(a)},a.successor=function(a){var b="abcdefghijklmnopqrstuvwxyz",c=b.length,d=a,e=a.length;while(e>=0){var f=a.charAt(--e),g="",h=!1;if(isNaN(f)){index=b.indexOf(f.toLowerCase());if(index===-1)g=f,h=!0;else{var i=f===f.toUpperCase();g=b.charAt((index+1)%c),i&&(g=g.toUpperCase()),h=index+1>=c;if(h&&e===0){var j=i?"A":"a";d=j+g+d.slice(1);break}}}else{g=+f+1,g>9&&(g=0,h=!0);if(h&&e===0){d="1"+g+d.slice(1);break}}d=d.slice(0,e)+g+d.slice(e+1);if(!h)break}return d},a.guid=function(a){var b=[],c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",d=c.length,a=a||32;for(var e=0;e<a;e++)b[e]=c.charAt(Math.floor(Math.random()*d));return b.join("")},a.lang="en",a.languages={},a.Language=b,b.prototype.addIrregular=function(a){for(var b=0,c=a.length;b<c;b++){var d=a[b];this.irregular.plural[d[0]]=d[1],this.irregular.singular[d[1]]=d[0]}},b.prototype.inflect=function(a,b){if(~this.uncountable.indexOf(a.toLowerCase()))return a;var c=this.irregular[b][a];if(c)return c;var d=this[b];for(var e=0,f=d.length;e<f;e++){var g=d[e][0];if(g.test(a))return a.replace(g,d[e][1])}return a},a.pluralize=function(b,c){return c||(c=a.lang),c=a.languages[c],c?c.inflect(b,"plural"):b},a.singularize=function(b,c){return c||(c=a.lang),c=a.languages[c],c?c.inflect(b,"singular"):b},a.addToPrototype=function(){for(key in a){if(key==="guid"||key==="lang"||key==="languages"||key==="Language"||key==="humanize"||key==="isString"||key==="version"||key==="addToPrototype")continue;(function(b){String.prototype[b]=function(){var c=Array.prototype.slice.call(arguments);return a[b].apply(a,[this].concat(c))}})(key)}};var c=a.languages.en=new a.Language;c.plural=[[/(todo)$/i,"$1s"],[/(matr|vert|ind)(?:ix|ex)$/i,"$1ices"],[/(octop|vir)us$/i,"$1i"],[/(alias|status)$/i,"$1es"],[/(cris|ax|test)is$/i,"$1es"],[/(s|ss|sh|ch|x|o)$/i,"$1es"],[/y$/i,"ies"],[/(o|e)y$/i,"$1ys"],[/([ti])um$/i,"$1a"],[/sis$/i,"ses"],[/(?:([^f])fe|([lr])f)$/i,"$1$2ves"],[/([^aeiouy]|qu)y$/i,"$1ies"],[/([m|l])ouse$/i,"$1ice"],[/^(ox)$/i,"$1en"],[/(quiz)$/i,"$1zes"],[/$/,"s"]],c.singular=[[/(bu|mis|kis)s$/i,"$1s"],[/([ti])a$/i,"$1um"],[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i,"$1$2sis"],[/(^analy)ses$/i,"$1sis"],[/([^f])ves$/i,"$1fe"],[/([lr])ves$/i,"$1f"],[/([^aeiouy]|qu)ies$/i,"$1y"],[/ies$/i,"ie"],[/(x|ch|ss|sh)es$/i,"$1"],[/([m|l])ice$/i,"$1ouse"],[/(bus)es$/i,"$1"],[/(shoe)s$/i,"$1"],[/(o)es$/i,"$1"],[/(cris|ax|test)es$/i,"$1is"],[/(octop|vir)i$/i,"$1us"],[/(alias|status)es$/i,"$1"],[/^(ox)en/i,"$1"],[/(vert|ind)ices$/i,"$1ex"],[/(matr)ices$/i,"$1ix"],[/(quiz)zes$/i,"$1"],[/s$/i,""]],c.addIrregular([["i","we"],["person","people"],["man","men"],["child","children"],["move","moves"],["she","they"],["he","they"],["myself","ourselves"],["yourself","ourselves"],["himself","themselves"],["herself","themselves"],["themself","themselves"],["mine","ours"],["hers","theirs"],["his","theirs"],["its","theirs"],["theirs","theirs"],["sex","sexes"],["this","that"]]),c.uncountable=["advice","enegery","excretion","digestion","cooperation","health","justice","jeans","labour","machinery","equipment","information","pollution","sewage","paper","money","species","series","rain","rice","fish","sheep","moose","deer","bison","proceedings","shears","pincers","breeches","hijinks","clippers","chassis","innings","elk","rhinoceros","swine","you","news"]})() |
49
test.js
@@ -106,2 +106,49 @@ var slang = require('./slang'), | ||
assert.equal(32, slang.guid().length, 'slang.guid failed'); | ||
assert.equal(16, slang.guid(16).length, 'slang.guid failed'); | ||
assert.equal(16, slang.guid(16).length, 'slang.guid failed'); | ||
// Test **slang.pluralize** | ||
assert.equal(slang.pluralize('cooperation'), 'cooperation'); | ||
assert.equal(slang.pluralize('man'), 'men'); | ||
assert.equal(slang.pluralize('quiz'), 'quizzes'); | ||
assert.equal(slang.pluralize('battery'), 'batteries'); | ||
assert.equal(slang.pluralize('bus'), 'buses'); | ||
assert.equal(slang.pluralize('mouse'), 'mice'); | ||
assert.equal(slang.pluralize('alias'), 'aliases'); | ||
assert.equal(slang.pluralize('octopus'), 'octopi'); | ||
assert.equal(slang.pluralize('fox'), 'foxes'); | ||
assert.equal(slang.pluralize('matrix'), 'matrices'); | ||
assert.equal(slang.pluralize('update'), 'updates'); | ||
assert.equal(slang.pluralize('potato'), 'potatoes'); | ||
assert.equal(slang.pluralize('todo'), 'todos'); | ||
assert.equal(slang.pluralize('sheep'), 'sheep'); | ||
assert.equal(slang.pluralize('person'), 'people'); | ||
assert.equal(slang.pluralize('this'), 'that'); | ||
assert.equal(slang.pluralize('crisis'), 'crises'); | ||
// Test **slang.singularize** | ||
assert.equal(slang.singularize('buses'), 'bus'); | ||
assert.equal(slang.singularize('wives'), 'wife'); | ||
assert.equal(slang.singularize('sheep'), 'sheep'); | ||
assert.equal(slang.singularize('lamps'), 'lamp'); | ||
assert.equal(slang.singularize('octopi'), 'octopus'); | ||
assert.equal(slang.singularize('crises'), 'crisis'); | ||
assert.equal(slang.singularize('mice'), 'mouse'); | ||
assert.equal(slang.singularize('families'), 'family'); | ||
assert.equal(slang.singularize('vertices'), 'vertex'); | ||
assert.equal(slang.singularize('men'), 'man'); | ||
assert.equal(slang.singularize('shoes'), 'shoe'); | ||
assert.equal(slang.singularize('synopses'), 'synopsis'); | ||
assert.equal(slang.singularize('batteries'), 'battery'); | ||
assert.equal(slang.singularize('updates'), 'update'); | ||
assert.equal(slang.singularize('people'), 'person'); | ||
assert.equal(slang.singularize('that'), 'this'); | ||
assert.equal(slang.singularize('foxes'), 'fox'); | ||
assert.equal(slang.singularize('todos'), 'todo'); | ||
assert.equal(slang.singularize('potatoes'), 'potato'); | ||
// Test **slang.language** | ||
slang.lang = 'foo'; | ||
assert.equal(slang.pluralize('bus'), 'bus'); | ||
assert.equal(slang.pluralize('bus', 'en'), 'buses'); | ||
assert.equal(slang.singularize('men'), 'men'); | ||
assert.equal(slang.singularize('men', 'en'), 'man'); |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
120823
707
204
0
1