Skip to content

Commit

Permalink
Merge pull request #1125 from stefanpenner/jj-abrams
Browse files Browse the repository at this point in the history
Ember.Inflector: Ember.String#pluralize Ember.String#singularize
  • Loading branch information
wycats committed Aug 24, 2013
2 parents 9683195 + 5155d97 commit 9325a1d
Show file tree
Hide file tree
Showing 12 changed files with 413 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Assetfile
@@ -1,5 +1,5 @@
distros = {
:full => %w(ember-data)
:full => %w(ember-data, ember-inflector)
}

#MEGAHAX
Expand Down
1 change: 1 addition & 0 deletions ember-dev.yml
Expand Up @@ -14,3 +14,4 @@ testing_suites:
- "package=all&dist=build&nojshint=true"
testing_packages:
- ember-data
- ember-inflector
3 changes: 2 additions & 1 deletion packages/ember-data/package.json
Expand Up @@ -12,7 +12,8 @@

"dependencies": {
"spade": "~> 1.0",
"ember-runtime": ">= 0"
"ember-runtime": ">= 0",
"ember-inflector": "1.0.0-rc.7"
},
"dependencies:development": {
"spade-qunit": "~> 1.0.0"
Expand Down
23 changes: 23 additions & 0 deletions packages/ember-inflector/lib/ext/string.js
@@ -0,0 +1,23 @@
require('ember-inflector/system/string');

if (Ember.EXTEND_PROTOTYPES) {
/**
See {{#crossLink "Ember.String/pluralize"}}{{/crossLink}}
@method pluralize
@for String
*/
String.prototype.pluralize = function() {
return Ember.String.pluralize(this);
};

/**
See {{#crossLink "Ember.String/singularize"}}{{/crossLink}}
@method singularize
@for String
*/
String.prototype.singularize = function() {
return Ember.String.singularize(this);
};
}
1 change: 1 addition & 0 deletions packages/ember-inflector/lib/main.js
@@ -0,0 +1 @@
require('ember-inflector/system');
6 changes: 6 additions & 0 deletions packages/ember-inflector/lib/system.js
@@ -0,0 +1,6 @@
require('ember-inflector/system/string');
require('ember-inflector/system/inflector');
require('ember-inflector/system/inflections');
require('ember-inflector/ext/string');

Ember.Inflector.inflector = new Ember.Inflector(Ember.Inflector.defaultRules);
78 changes: 78 additions & 0 deletions packages/ember-inflector/lib/system/inflections.js
@@ -0,0 +1,78 @@
Ember.Inflector.defaultRules = {
plurals: [
[/$/, 's'],
[/s$/i, 's'],
[/^(ax|test)is$/i, '$1es'],
[/(octop|vir)us$/i, '$1i'],
[/(octop|vir)i$/i, '$1i'],
[/(alias|status)$/i, '$1es'],
[/(bu)s$/i, '$1ses'],
[/(buffal|tomat)o$/i, '$1oes'],
[/([ti])um$/i, '$1a'],
[/([ti])a$/i, '$1a'],
[/sis$/i, 'ses'],
[/(?:([^f])fe|([lr])f)$/i, '$1$2ves'],
[/(hive)$/i, '$1s'],
[/([^aeiouy]|qu)y$/i, '$1ies'],
[/(x|ch|ss|sh)$/i, '$1es'],
[/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'],
[/^(m|l)ouse$/i, '$1ice'],
[/^(m|l)ice$/i, '$1ice'],
[/^(ox)$/i, '$1en'],
[/^(oxen)$/i, '$1'],
[/(quiz)$/i, '$1zes']
],

singular: [
[/s$/i, ''],
[/(ss)$/i, '$1'],
[/(n)ews$/i, '$1ews'],
[/([ti])a$/i, '$1um'],
[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1sis'],
[/(^analy)(sis|ses)$/i, '$1sis'],
[/([^f])ves$/i, '$1fe'],
[/(hive)s$/i, '$1'],
[/(tive)s$/i, '$1'],
[/([lr])ves$/i, '$1f'],
[/([^aeiouy]|qu)ies$/i, '$1y'],
[/(s)eries$/i, '$1eries'],
[/(m)ovies$/i, '$1ovie'],
[/(x|ch|ss|sh)es$/i, '$1'],
[/^(m|l)ice$/i, '$1ouse'],
[/(bus)(es)?$/i, '$1'],
[/(o)es$/i, '$1'],
[/(shoe)s$/i, '$1'],
[/(cris|test)(is|es)$/i, '$1is'],
[/^(a)x[ie]s$/i, '$1xis'],
[/(octop|vir)(us|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'],
[/(database)s$/i, '$1']
],

irregularPairs: [
['person', 'people'],
['man', 'men'],
['child', 'children'],
['sex', 'sexes'],
['move', 'moves'],
['cow', 'kine'],
['zombie', 'zombies']
],

uncountable: [
'equipment',
'information',
'rice',
'money',
'species',
'series',
'fish',
'sheep',
'jeans',
'police'
]
};
96 changes: 96 additions & 0 deletions packages/ember-inflector/lib/system/inflector.js
@@ -0,0 +1,96 @@
var BLANK_REGEX = /^\s*$/;

function loadUncountable(rules, uncountable) {
for (var i = 0, length = uncountable.length; i < length; i++) {
rules.uncountable[uncountable[i]] = true;
}
}

function loadIrregular(rules, irregularPairs) {
var pair;

for (var i = 0, length = irregularPairs.length; i < length; i++) {
pair = irregularPairs[i];

rules.irregular[pair[0]] = pair[1];
rules.irregularInverse[pair[1]] = pair[0];
}
}

function Inflector(ruleSet) {
ruleSet = ruleSet || {};
ruleSet.uncountable = ruleSet.uncountable || {};
ruleSet.irregularPairs= ruleSet.irregularPairs|| {};

var rules = this.rules = {
plurals: ruleSet.plurals || [],
singular: ruleSet.singular || [],
irregular: {},
irregularInverse: {},
uncountable: {}
};

loadUncountable(rules, ruleSet.uncountable);
loadIrregular(rules, ruleSet.irregularPairs);
}

Inflector.prototype = {
pluralize: function(word) {
return this.inflect(word, this.rules.plurals);
},

singularize: function(word) {
return this.inflect(word, this.rules.singular);
},

inflect: function(word, typeRules) {
var inflection, substitution, result, lowercase, isBlank,
isUncountable, isIrregular, isIrregularInverse, rule;

isBlank = BLANK_REGEX.test(word);

if (isBlank) {
return word;
}

lowercase = word.toLowerCase();

isUncountable = this.rules.uncountable[lowercase];

if (isUncountable) {
return word;
}

isIrregular = this.rules.irregular[lowercase];

if (isIrregular) {
return isIrregular;
}

isIrregularInverse = this.rules.irregularInverse[lowercase];

if (isIrregularInverse) {
return isIrregularInverse;
}

for (var i = typeRules.length, min = 0; i > min; i--) {
inflection = typeRules[i-1];
rule = inflection[0];

if (rule.test(word)) {
break;
}
}

inflection = inflection || [];

rule = inflection[0];
substitution = inflection[1];

result = word.replace(rule, substitution);

return result;
}
};

Ember.Inflector = Inflector;
7 changes: 7 additions & 0 deletions packages/ember-inflector/lib/system/string.js
@@ -0,0 +1,7 @@
Ember.String.pluralize = function(word) {
return Ember.Inflector.inflector.pluralize(word);
};

Ember.String.singularize = function(word) {
return Ember.Inflector.inflector.singularize(word);
};
23 changes: 23 additions & 0 deletions packages/ember-inflector/package.json
@@ -0,0 +1,23 @@
{
"name": "ember-inflector",
"summary": "Ember Inflections",
"descrption": "",
"homepage": "http://github.com/emberjs/ember.js",
"author": ["Stefan Penner"],
"version": "1.0.0-rc.7",

"directories":{
"lib": "lib"
},

"dependencies": {
"ember-runtime": ">= 0"
},

"bpm:build": {
"bpm_lib.js": {
"files": ["lib"],
"modes": "*"
}
}
}

0 comments on commit 9325a1d

Please sign in to comment.