Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / Inflector.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-util-Inflector'>/**
19 </span> * @class Ext.util.Inflector
20  * @extends Object
21  * &lt;p&gt;General purpose inflector class that {@link #pluralize pluralizes}, {@link #singularize singularizes} and 
22  * {@link #ordinalize ordinalizes} words. Sample usage:&lt;/p&gt;
23  * 
24 &lt;pre&gt;&lt;code&gt;
25 //turning singular words into plurals
26 Ext.util.Inflector.pluralize('word'); //'words'
27 Ext.util.Inflector.pluralize('person'); //'people'
28 Ext.util.Inflector.pluralize('sheep'); //'sheep'
29
30 //turning plurals into singulars
31 Ext.util.Inflector.singularize('words'); //'word'
32 Ext.util.Inflector.singularize('people'); //'person'
33 Ext.util.Inflector.singularize('sheep'); //'sheep'
34
35 //ordinalizing numbers
36 Ext.util.Inflector.ordinalize(11); //&quot;11th&quot;
37 Ext.util.Inflector.ordinalize(21); //&quot;21th&quot;
38 Ext.util.Inflector.ordinalize(1043); //&quot;1043rd&quot;
39 &lt;/code&gt;&lt;/pre&gt;
40  * 
41  * &lt;p&gt;&lt;u&gt;Customization&lt;/u&gt;&lt;/p&gt;
42  * 
43  * &lt;p&gt;The Inflector comes with a default set of US English pluralization rules. These can be augmented with additional
44  * rules if the default rules do not meet your application's requirements, or swapped out entirely for other languages.
45  * Here is how we might add a rule that pluralizes &quot;ox&quot; to &quot;oxen&quot;:&lt;/p&gt;
46  * 
47 &lt;pre&gt;&lt;code&gt;
48 Ext.util.Inflector.plural(/^(ox)$/i, &quot;$1en&quot;);
49 &lt;/code&gt;&lt;/pre&gt;
50  * 
51  * &lt;p&gt;Each rule consists of two items - a regular expression that matches one or more rules, and a replacement string.
52  * In this case, the regular expression will only match the string &quot;ox&quot;, and will replace that match with &quot;oxen&quot;. 
53  * Here's how we could add the inverse rule:&lt;/p&gt;
54  * 
55 &lt;pre&gt;&lt;code&gt;
56 Ext.util.Inflector.singular(/^(ox)en$/i, &quot;$1&quot;);
57 &lt;/code&gt;&lt;/pre&gt;
58  * 
59  * &lt;p&gt;Note that the ox/oxen rules are present by default.&lt;/p&gt;
60  * 
61  * @singleton
62  */
63
64 Ext.define('Ext.util.Inflector', {
65
66     /* Begin Definitions */
67
68     singleton: true,
69
70     /* End Definitions */
71
72 <span id='Ext-util-Inflector-property-plurals'>    /**
73 </span>     * @private
74      * The registered plural tuples. Each item in the array should contain two items - the first must be a regular
75      * expression that matchers the singular form of a word, the second must be a String that replaces the matched
76      * part of the regular expression. This is managed by the {@link #plural} method.
77      * @property plurals
78      * @type Array
79      */
80     plurals: [
81         [(/(quiz)$/i),                &quot;$1zes&quot;  ],
82         [(/^(ox)$/i),                 &quot;$1en&quot;   ],
83         [(/([m|l])ouse$/i),           &quot;$1ice&quot;  ],
84         [(/(matr|vert|ind)ix|ex$/i),  &quot;$1ices&quot; ],
85         [(/(x|ch|ss|sh)$/i),          &quot;$1es&quot;   ],
86         [(/([^aeiouy]|qu)y$/i),       &quot;$1ies&quot;  ],
87         [(/(hive)$/i),                &quot;$1s&quot;    ],
88         [(/(?:([^f])fe|([lr])f)$/i),  &quot;$1$2ves&quot;],
89         [(/sis$/i),                   &quot;ses&quot;    ],
90         [(/([ti])um$/i),              &quot;$1a&quot;    ],
91         [(/(buffal|tomat|potat)o$/i), &quot;$1oes&quot;  ],
92         [(/(bu)s$/i),                 &quot;$1ses&quot;  ],
93         [(/(alias|status|sex)$/i),    &quot;$1es&quot;   ],
94         [(/(octop|vir)us$/i),         &quot;$1i&quot;    ],
95         [(/(ax|test)is$/i),           &quot;$1es&quot;   ],
96         [(/^person$/),                &quot;people&quot; ],
97         [(/^man$/),                   &quot;men&quot;    ],
98         [(/^(child)$/),               &quot;$1ren&quot;  ],
99         [(/s$/i),                     &quot;s&quot;      ],
100         [(/$/),                       &quot;s&quot;      ]
101     ],
102     
103 <span id='Ext-util-Inflector-property-singulars'>    /**
104 </span>     * @private
105      * The set of registered singular matchers. Each item in the array should contain two items - the first must be a 
106      * regular expression that matches the plural form of a word, the second must be a String that replaces the 
107      * matched part of the regular expression. This is managed by the {@link #singular} method.
108      * @property singulars
109      * @type Array
110      */
111     singulars: [
112       [(/(quiz)zes$/i),                                                    &quot;$1&quot;     ],
113       [(/(matr)ices$/i),                                                   &quot;$1ix&quot;   ],
114       [(/(vert|ind)ices$/i),                                               &quot;$1ex&quot;   ],
115       [(/^(ox)en/i),                                                       &quot;$1&quot;     ],
116       [(/(alias|status)es$/i),                                             &quot;$1&quot;     ],
117       [(/(octop|vir)i$/i),                                                 &quot;$1us&quot;   ],
118       [(/(cris|ax|test)es$/i),                                             &quot;$1is&quot;   ],
119       [(/(shoe)s$/i),                                                      &quot;$1&quot;     ],
120       [(/(o)es$/i),                                                        &quot;$1&quot;     ],
121       [(/(bus)es$/i),                                                      &quot;$1&quot;     ],
122       [(/([m|l])ice$/i),                                                   &quot;$1ouse&quot; ],
123       [(/(x|ch|ss|sh)es$/i),                                               &quot;$1&quot;     ],
124       [(/(m)ovies$/i),                                                     &quot;$1ovie&quot; ],
125       [(/(s)eries$/i),                                                     &quot;$1eries&quot;],
126       [(/([^aeiouy]|qu)ies$/i),                                            &quot;$1y&quot;    ],
127       [(/([lr])ves$/i),                                                    &quot;$1f&quot;    ],
128       [(/(tive)s$/i),                                                      &quot;$1&quot;     ],
129       [(/(hive)s$/i),                                                      &quot;$1&quot;     ],
130       [(/([^f])ves$/i),                                                    &quot;$1fe&quot;   ],
131       [(/(^analy)ses$/i),                                                  &quot;$1sis&quot;  ],
132       [(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i), &quot;$1$2sis&quot;],
133       [(/([ti])a$/i),                                                      &quot;$1um&quot;   ],
134       [(/(n)ews$/i),                                                       &quot;$1ews&quot;  ],
135       [(/people$/i),                                                       &quot;person&quot; ],
136       [(/s$/i),                                                            &quot;&quot;       ]
137     ],
138     
139 <span id='Ext-util-Inflector-property-uncountable'>    /**
140 </span>     * @private
141      * The registered uncountable words
142      * @property uncountable
143      * @type Array
144      */
145      uncountable: [
146         &quot;sheep&quot;,
147         &quot;fish&quot;,
148         &quot;series&quot;,
149         &quot;species&quot;,
150         &quot;money&quot;,
151         &quot;rice&quot;,
152         &quot;information&quot;,
153         &quot;equipment&quot;,
154         &quot;grass&quot;,
155         &quot;mud&quot;,
156         &quot;offspring&quot;,
157         &quot;deer&quot;,
158         &quot;means&quot;
159     ],
160     
161 <span id='Ext-util-Inflector-method-singular'>    /**
162 </span>     * Adds a new singularization rule to the Inflector. See the intro docs for more information
163      * @param {RegExp} matcher The matcher regex
164      * @param {String} replacer The replacement string, which can reference matches from the matcher argument
165      */
166     singular: function(matcher, replacer) {
167         this.singulars.unshift([matcher, replacer]);
168     },
169     
170 <span id='Ext-util-Inflector-method-plural'>    /**
171 </span>     * Adds a new pluralization rule to the Inflector. See the intro docs for more information
172      * @param {RegExp} matcher The matcher regex
173      * @param {String} replacer The replacement string, which can reference matches from the matcher argument
174      */
175     plural: function(matcher, replacer) {
176         this.plurals.unshift([matcher, replacer]);
177     },
178     
179 <span id='Ext-util-Inflector-method-clearSingulars'>    /**
180 </span>     * Removes all registered singularization rules
181      */
182     clearSingulars: function() {
183         this.singulars = [];
184     },
185     
186 <span id='Ext-util-Inflector-method-clearPlurals'>    /**
187 </span>     * Removes all registered pluralization rules
188      */
189     clearPlurals: function() {
190         this.plurals = [];
191     },
192     
193 <span id='Ext-util-Inflector-method-isTransnumeral'>    /**
194 </span>     * Returns true if the given word is transnumeral (the word is its own singular and plural form - e.g. sheep, fish)
195      * @param {String} word The word to test
196      * @return {Boolean} True if the word is transnumeral
197      */
198     isTransnumeral: function(word) {
199         return Ext.Array.indexOf(this.uncountable, word) != -1;
200     },
201
202 <span id='Ext-util-Inflector-method-pluralize'>    /**
203 </span>     * Returns the pluralized form of a word (e.g. Ext.util.Inflector.pluralize('word') returns 'words')
204      * @param {String} word The word to pluralize
205      * @return {String} The pluralized form of the word
206      */
207     pluralize: function(word) {
208         if (this.isTransnumeral(word)) {
209             return word;
210         }
211
212         var plurals = this.plurals,
213             length  = plurals.length,
214             tuple, regex, i;
215         
216         for (i = 0; i &lt; length; i++) {
217             tuple = plurals[i];
218             regex = tuple[0];
219             
220             if (regex == word || (regex.test &amp;&amp; regex.test(word))) {
221                 return word.replace(regex, tuple[1]);
222             }
223         }
224         
225         return word;
226     },
227     
228 <span id='Ext-util-Inflector-method-singularize'>    /**
229 </span>     * Returns the singularized form of a word (e.g. Ext.util.Inflector.singularize('words') returns 'word')
230      * @param {String} word The word to singularize
231      * @return {String} The singularized form of the word
232      */
233     singularize: function(word) {
234         if (this.isTransnumeral(word)) {
235             return word;
236         }
237
238         var singulars = this.singulars,
239             length    = singulars.length,
240             tuple, regex, i;
241         
242         for (i = 0; i &lt; length; i++) {
243             tuple = singulars[i];
244             regex = tuple[0];
245             
246             if (regex == word || (regex.test &amp;&amp; regex.test(word))) {
247                 return word.replace(regex, tuple[1]);
248             }
249         }
250         
251         return word;
252     },
253     
254 <span id='Ext-util-Inflector-method-classify'>    /**
255 </span>     * Returns the correct {@link Ext.data.Model Model} name for a given string. Mostly used internally by the data 
256      * package
257      * @param {String} word The word to classify
258      * @return {String} The classified version of the word
259      */
260     classify: function(word) {
261         return Ext.String.capitalize(this.singularize(word));
262     },
263     
264 <span id='Ext-util-Inflector-method-ordinalize'>    /**
265 </span>     * Ordinalizes a given number by adding a prefix such as 'st', 'nd', 'rd' or 'th' based on the last digit of the 
266      * number. 21 -&gt; 21st, 22 -&gt; 22nd, 23 -&gt; 23rd, 24 -&gt; 24th etc
267      * @param {Number} number The number to ordinalize
268      * @return {String} The ordinalized number
269      */
270     ordinalize: function(number) {
271         var parsed = parseInt(number, 10),
272             mod10  = parsed % 10,
273             mod100 = parsed % 100;
274         
275         //11 through 13 are a special case
276         if (11 &lt;= mod100 &amp;&amp; mod100 &lt;= 13) {
277             return number + &quot;th&quot;;
278         } else {
279             switch(mod10) {
280                 case 1 : return number + &quot;st&quot;;
281                 case 2 : return number + &quot;nd&quot;;
282                 case 3 : return number + &quot;rd&quot;;
283                 default: return number + &quot;th&quot;;
284             }
285         }
286     }
287 }, function() {
288     //aside from the rules above, there are a number of words that have irregular pluralization so we add them here
289     var irregulars = {
290             alumnus: 'alumni',
291             cactus : 'cacti',
292             focus  : 'foci',
293             nucleus: 'nuclei',
294             radius: 'radii',
295             stimulus: 'stimuli',
296             ellipsis: 'ellipses',
297             paralysis: 'paralyses',
298             oasis: 'oases',
299             appendix: 'appendices',
300             index: 'indexes',
301             beau: 'beaux',
302             bureau: 'bureaux',
303             tableau: 'tableaux',
304             woman: 'women',
305             child: 'children',
306             man: 'men',
307             corpus:     'corpora',
308             criterion: 'criteria',
309             curriculum: 'curricula',
310             genus: 'genera',
311             memorandum: 'memoranda',
312             phenomenon: 'phenomena',
313             foot: 'feet',
314             goose: 'geese',
315             tooth: 'teeth',
316             antenna: 'antennae',
317             formula: 'formulae',
318             nebula: 'nebulae',
319             vertebra: 'vertebrae',
320             vita: 'vitae'
321         },
322         singular;
323     
324     for (singular in irregulars) {
325         this.plural(singular, irregulars[singular]);
326         this.singular(irregulars[singular], singular);
327     }
328 });</pre>
329 </body>
330 </html>