0
|
1 <#@ import namespace="System" #>
|
|
2 <#@ import namespace="System.Collections.Generic" #>
|
|
3 <#@ import namespace="System.Text" #>
|
|
4 <#@ import namespace="System.Text.RegularExpressions" #>
|
|
5 <#
|
|
6 {
|
|
7 var psPrevAfterLoadMetadata = AfterLoadMetadata;
|
|
8
|
|
9 AfterLoadMetadata = _ =>
|
|
10 {
|
|
11 psPrevAfterLoadMetadata(_);
|
|
12
|
|
13 if (PluralizeDataContextPropertyNames || SingularizeDataContextPropertyNames)
|
|
14 {
|
|
15 foreach (var t in Tables.Values)
|
|
16 {
|
|
17 var propName = t.DataContextPropertyName ?? t.ClassName ?? t.TableName;
|
|
18 var newName = PluralizeDataContextPropertyNames ? ToPlural(propName) : ToSingular(propName);
|
|
19
|
|
20 t.DataContextPropertyName = newName;
|
|
21 }
|
|
22 }
|
|
23
|
|
24 if (PluralizeClassNames || SingularizeClassNames)
|
|
25 {
|
|
26 foreach (var t in Tables.Values)
|
|
27 {
|
|
28 var className = t.ClassName ?? t.TableName;
|
|
29 var newName = PluralizeClassNames ? ToPlural(className) : ToSingular(className);
|
|
30
|
|
31 t.ClassName = newName;
|
|
32 }
|
|
33 }
|
|
34 };
|
|
35
|
|
36 PluralizeAssociationName = ToPlural;
|
|
37 SingularizeAssociationName = ToSingular;
|
|
38 }
|
|
39
|
|
40 #><#+
|
|
41
|
|
42 bool PluralizeClassNames = false;
|
|
43 bool SingularizeClassNames = true;
|
|
44 bool PluralizeDataContextPropertyNames = true;
|
|
45 bool SingularizeDataContextPropertyNames = false;
|
|
46
|
|
47 string ToPlural(string str)
|
|
48 {
|
|
49 var word = GetLastWord(str);
|
|
50 var newWord = Plurals.ToPlural(word);
|
|
51
|
|
52 if (word != newWord)
|
|
53 {
|
|
54 if (char.IsUpper(word[0]))
|
|
55 newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1);
|
|
56
|
|
57 return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord;
|
|
58 }
|
|
59
|
|
60 return str;
|
|
61 }
|
|
62
|
|
63 string ToSingular(string str)
|
|
64 {
|
|
65 var word = GetLastWord(str);
|
|
66 var newWord = Plurals.ToSingular(word);
|
|
67
|
|
68 if (word != newWord)
|
|
69 {
|
|
70 if (char.IsUpper(word[0]))
|
|
71 newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1);
|
|
72
|
|
73 return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord;
|
|
74 }
|
|
75
|
|
76 return str;
|
|
77 }
|
|
78
|
|
79 string GetLastWord(string word)
|
|
80 {
|
|
81 if (string.IsNullOrEmpty(word))
|
|
82 return word;
|
|
83
|
|
84 var len = word.Length;
|
|
85 var n = len - 1;
|
|
86
|
|
87 if (char.IsLower(word[n]))
|
|
88 {
|
|
89 for (; n > 0 && char.IsLower(word[n]); n--);
|
|
90 }
|
|
91 else
|
|
92 {
|
|
93 for (; n > 0 && char.IsUpper(word[n]); n--);
|
|
94 if (char.IsLower(word[n]))
|
|
95 n++;
|
|
96 }
|
|
97
|
|
98 return n > 0 ? word.Substring(n) : word;
|
|
99 }
|
|
100
|
|
101 // Shamelessly jacked from http://www.bennysutton.com/C-sharp/Plural-Singular-Words.aspx with little modifications.
|
|
102 //
|
|
103
|
|
104 //using System;
|
|
105 //using System.Collections.Generic;
|
|
106 //using System.Text;
|
|
107 //using System.Text.RegularExpressions;
|
|
108
|
|
109 /// <summary>
|
|
110 /// Convert words to and from singulars/plurals
|
|
111 /// Copyright www.BennySutton.com 2008
|
|
112 /// You may reuse this code BUT not for sale AND ONLY with credit to www.BennySutton.com
|
|
113 /// </summary>
|
|
114 public sealed class Plurals
|
|
115 {
|
|
116 /// <summary>
|
|
117 /// Store irregular plurals in a dictionary
|
|
118 /// </summary>
|
|
119 private static Dictionary<string, string> _dictionary = new Dictionary<string, string>();
|
|
120
|
|
121 #region Constructors
|
|
122
|
|
123 /// <summary>
|
|
124 /// The singleton instance (thanks to dotnetpearls.com for help here)
|
|
125 /// </summary>
|
|
126 static readonly Plurals _instance = new Plurals();
|
|
127 /// <summary>
|
|
128 /// Get an instance of the structure singleton. This effectively caches the dictionary
|
|
129 /// </summary>
|
|
130 public static Plurals Instance
|
|
131 {
|
|
132 get
|
|
133 {
|
|
134 // Fastest solution that avoids null check and is thread-safe
|
|
135 // because of readonly keyword.
|
|
136 return _instance;
|
|
137 }
|
|
138 }
|
|
139
|
|
140 /// <summary>
|
|
141 /// Run initialization on this singleton class
|
|
142 /// </summary>
|
|
143 private Plurals()
|
|
144 {
|
|
145 Initialize();
|
|
146 }
|
|
147
|
|
148 private void Initialize()
|
|
149 {
|
|
150 //to test that this class only initializes once uncomment next line
|
|
151 //System.Web.HttpContext.Current.Response.Write("initializing singleton <br>");
|
|
152 // irregular plurals
|
|
153 _dictionary.Add("access", "accesses");
|
|
154 _dictionary.Add("afterlife", "afterlives");
|
|
155 _dictionary.Add("alga", "algae");
|
|
156 _dictionary.Add("alumna", "alumnae");
|
|
157 _dictionary.Add("alumnus", "alumni");
|
|
158 _dictionary.Add("analysis", "analyses");
|
|
159 _dictionary.Add("antenna", "antennae");
|
|
160 _dictionary.Add("appendix", "appendices");
|
|
161 _dictionary.Add("axis", "axes");
|
|
162 _dictionary.Add("bacillus", "bacilli");
|
|
163 _dictionary.Add("basis", "bases");
|
|
164 _dictionary.Add("Bedouin", "Bedouin");
|
|
165 _dictionary.Add("cactus", "cacti");
|
|
166 _dictionary.Add("calf", "calves");
|
|
167 _dictionary.Add("cherub", "cherubim");
|
|
168 _dictionary.Add("child", "children");
|
|
169 _dictionary.Add("cod", "cod");
|
|
170 _dictionary.Add("cookie", "cookies");
|
|
171 _dictionary.Add("criterion", "criteria");
|
|
172 _dictionary.Add("curriculum", "curricula");
|
|
173 _dictionary.Add("data", "data");
|
|
174 _dictionary.Add("deer", "deer");
|
|
175 _dictionary.Add("diagnosis", "diagnoses");
|
|
176 _dictionary.Add("die", "dice");
|
|
177 _dictionary.Add("dormouse", "dormice");
|
|
178 _dictionary.Add("elf", "elves");
|
|
179 _dictionary.Add("elk", "elk");
|
|
180 _dictionary.Add("erratum", "errata");
|
|
181 _dictionary.Add("esophagus", "esophagi");
|
|
182 _dictionary.Add("fauna", "faunae");
|
|
183 _dictionary.Add("fish", "fish");
|
|
184 _dictionary.Add("flora", "florae");
|
|
185 _dictionary.Add("focus", "foci");
|
|
186 _dictionary.Add("foot", "feet");
|
|
187 _dictionary.Add("formula", "formulae");
|
|
188 _dictionary.Add("fundus", "fundi");
|
|
189 _dictionary.Add("fungus", "fungi");
|
|
190 _dictionary.Add("genie", "genii");
|
|
191 _dictionary.Add("genus", "genera");
|
|
192 _dictionary.Add("goose", "geese");
|
|
193 _dictionary.Add("grouse", "grouse");
|
|
194 _dictionary.Add("hake", "hake");
|
|
195 _dictionary.Add("half", "halves");
|
|
196 _dictionary.Add("headquarters", "headquarters");
|
|
197 _dictionary.Add("hippo", "hippos");
|
|
198 _dictionary.Add("hippopotamus", "hippopotami");
|
|
199 _dictionary.Add("hoof", "hooves");
|
|
200 _dictionary.Add("housewife", "housewives");
|
|
201 _dictionary.Add("hypothesis", "hypotheses");
|
|
202 _dictionary.Add("index", "indices");
|
|
203 _dictionary.Add("jackknife", "jackknives");
|
|
204 _dictionary.Add("knife", "knives");
|
|
205 _dictionary.Add("labium", "labia");
|
|
206 _dictionary.Add("larva", "larvae");
|
|
207 _dictionary.Add("leaf", "leaves");
|
|
208 _dictionary.Add("life", "lives");
|
|
209 _dictionary.Add("loaf", "loaves");
|
|
210 _dictionary.Add("louse", "lice");
|
|
211 _dictionary.Add("magus", "magi");
|
|
212 _dictionary.Add("man", "men");
|
|
213 _dictionary.Add("memorandum", "memoranda");
|
|
214 _dictionary.Add("midwife", "midwives");
|
|
215 _dictionary.Add("millennium", "millennia");
|
|
216 _dictionary.Add("moose", "moose");
|
|
217 _dictionary.Add("mouse", "mice");
|
|
218 _dictionary.Add("nebula", "nebulae");
|
|
219 _dictionary.Add("neurosis", "neuroses");
|
|
220 _dictionary.Add("nova", "novas");
|
|
221 _dictionary.Add("nucleus", "nuclei");
|
|
222 _dictionary.Add("oesophagus", "oesophagi");
|
|
223 _dictionary.Add("offspring", "offspring");
|
|
224 _dictionary.Add("ovum", "ova");
|
|
225 _dictionary.Add("ox", "oxen");
|
|
226 _dictionary.Add("papyrus", "papyri");
|
|
227 _dictionary.Add("passerby", "passersby");
|
|
228 _dictionary.Add("penknife", "penknives");
|
|
229 _dictionary.Add("person", "people");
|
|
230 _dictionary.Add("phenomenon", "phenomena");
|
|
231 _dictionary.Add("placenta", "placentae");
|
|
232 _dictionary.Add("pocketknife", "pocketknives");
|
|
233 _dictionary.Add("process", "processes");
|
|
234 _dictionary.Add("pupa", "pupae");
|
|
235 _dictionary.Add("radius", "radii");
|
|
236 _dictionary.Add("reindeer", "reindeer");
|
|
237 _dictionary.Add("retina", "retinae");
|
|
238 _dictionary.Add("rhinoceros", "rhinoceros");
|
|
239 _dictionary.Add("roe", "roe");
|
|
240 _dictionary.Add("salmon", "salmon");
|
|
241 _dictionary.Add("scarf", "scarves");
|
|
242 _dictionary.Add("self", "selves");
|
|
243 _dictionary.Add("seraph", "seraphim");
|
|
244 _dictionary.Add("series", "series");
|
|
245 _dictionary.Add("sheaf", "sheaves");
|
|
246 _dictionary.Add("sheep", "sheep");
|
|
247 _dictionary.Add("shelf", "shelves");
|
|
248 _dictionary.Add("species", "species");
|
|
249 _dictionary.Add("spectrum", "spectra");
|
|
250 _dictionary.Add("status", "status");
|
|
251 _dictionary.Add("stimulus", "stimuli");
|
|
252 _dictionary.Add("stratum", "strata");
|
|
253 _dictionary.Add("supernova", "supernovas");
|
|
254 _dictionary.Add("swine", "swine");
|
|
255 _dictionary.Add("terminus", "termini");
|
|
256 _dictionary.Add("thesaurus", "thesauri");
|
|
257 _dictionary.Add("thesis", "theses");
|
|
258 _dictionary.Add("thief", "thieves");
|
|
259 _dictionary.Add("trout", "trout");
|
|
260 _dictionary.Add("vulva", "vulvae");
|
|
261 _dictionary.Add("wife", "wives");
|
|
262 _dictionary.Add("wildebeest", "wildebeest");
|
|
263 _dictionary.Add("wolf", "wolves");
|
|
264 _dictionary.Add("woman", "women");
|
|
265 _dictionary.Add("yen", "yen");
|
|
266 }
|
|
267
|
|
268 #endregion //Constructors
|
|
269
|
|
270 #region Methods
|
|
271
|
|
272 /// <summary>
|
|
273 /// Call this method to get the properly pluralized
|
|
274 /// English version of the word.
|
|
275 /// </summary>
|
|
276 /// <param name="word">The word needing conditional pluralization.</param>
|
|
277 /// <param name="count">The number of items the word refers to.</param>
|
|
278 /// <returns>The pluralized word</returns>
|
|
279 static public string ToPlural(string word)
|
|
280 {
|
|
281 word = word.ToLower();
|
|
282
|
|
283 if (_dictionary.ContainsKey(word))
|
|
284 //it's an irregular plural, use the word from the dictionary
|
|
285 {
|
|
286 return _dictionary[word];
|
|
287 }
|
|
288
|
|
289 if (TestIsPlural(word) == true)
|
|
290 {
|
|
291 return word; //it's already a plural
|
|
292 }
|
|
293
|
|
294 if (word.Length <= 2)
|
|
295 {
|
|
296 return word; //not a word that can be pluralised!
|
|
297 }
|
|
298
|
|
299 ////1. If the word ends in a consonant plus -y, change the -y into
|
|
300 ///-ie and add an -s to form the plural
|
|
301 ///e.g. enemy--enemies baby--babies
|
|
302 switch (word.Substring(word.Length - 2))
|
|
303 {
|
|
304 case "by":
|
|
305 case "cy":
|
|
306 case "dy":
|
|
307 case "fy":
|
|
308 case "gy":
|
|
309 case "hy":
|
|
310 case "jy":
|
|
311 case "ky":
|
|
312 case "ly":
|
|
313 case "my":
|
|
314 case "ny":
|
|
315 case "py":
|
|
316 case "ry":
|
|
317 case "sy":
|
|
318 case "ty":
|
|
319 case "vy":
|
|
320 case "wy":
|
|
321 case "xy":
|
|
322 case "zy":
|
|
323 {
|
|
324 return word.Substring(0, word.Length - 1) + "ies";
|
|
325 }
|
|
326
|
|
327 //2. For words that end in -is, change the -is to -es to make the plural form.
|
|
328 //synopsis--synopses
|
|
329 //thesis--theses
|
|
330 case "is":
|
|
331 {
|
|
332 return word.Substring(0, word.Length - 1) + "es";
|
|
333 }
|
|
334
|
|
335 //3. For words that end in a "hissing" sound (s,z,x,ch,sh), add an -es to form the plural.
|
|
336 //box--boxes
|
|
337 //church--churches
|
|
338 case "ch":
|
|
339 case "sh":
|
|
340 {
|
|
341 return word + "es";
|
|
342 }
|
|
343 default:
|
|
344 {
|
|
345 switch (word.Substring(word.Length - 1))
|
|
346 {
|
|
347 case "s":
|
|
348 case "z":
|
|
349 case "x":
|
|
350 {
|
|
351 return word + "es";
|
|
352 }
|
|
353 default:
|
|
354 {
|
|
355 //4. Assume add an -s to form the plural of most words.
|
|
356 return word + "s";
|
|
357 }
|
|
358 }
|
|
359 }
|
|
360 }
|
|
361 }
|
|
362
|
|
363 /// <summary>
|
|
364 /// Call this method to get the singular
|
|
365 /// version of a plural English word.
|
|
366 /// </summary>
|
|
367 /// <param name="word">The word to turn into a singular</param>
|
|
368 /// <returns>The singular word</returns>
|
|
369 static public string ToSingular(string word)
|
|
370 {
|
|
371 word = word.ToLower();
|
|
372
|
|
373 if (_dictionary.ContainsKey(word))
|
|
374 return word;
|
|
375
|
|
376 if (_dictionary.ContainsValue(word))
|
|
377 {
|
|
378 foreach (KeyValuePair<string, string> kvp in _dictionary)
|
|
379 {
|
|
380 if (kvp.Value == word) return kvp.Key;
|
|
381 }
|
|
382 }
|
|
383
|
|
384 if (word.Substring(word.Length - 1) != "s")
|
|
385 {
|
|
386 return word; // not a plural word if it doesn't end in S
|
|
387 }
|
|
388
|
|
389 if (word.Length <= 2)
|
|
390 {
|
|
391 return word; // not a word that can be made singular if only two letters!
|
|
392 }
|
|
393
|
|
394 if (word.Length >= 4)
|
|
395 {
|
|
396 // 1. If the word ends in a consonant plus -y, change the -y into -ie and add an -s to form the plural – so reverse engineer it to get the singular
|
|
397 // e.g. enemy--enemies baby--babies family--families
|
|
398 switch (word.Substring(word.Length - 4))
|
|
399 {
|
|
400 case "bies":
|
|
401 case "cies":
|
|
402 case "dies":
|
|
403 case "fies":
|
|
404 case "gies":
|
|
405 case "hies":
|
|
406 case "jies":
|
|
407 case "kies":
|
|
408 case "lies":
|
|
409 case "mies":
|
|
410 case "nies":
|
|
411 case "pies":
|
|
412 case "ries":
|
|
413 case "sies":
|
|
414 case "ties":
|
|
415 case "vies":
|
|
416 case "wies":
|
|
417 case "xies":
|
|
418 case "zies":
|
|
419 {
|
|
420 return word.Substring(0, word.Length - 3) + "y";
|
|
421 }
|
|
422 //3. For words that end in a "hissing" sound (s,z,x,ch,sh), add an -es to form the plural.
|
|
423 //church--churches
|
|
424 case "ches":
|
|
425 case "shes":
|
|
426 {
|
|
427 return word.Substring(0, word.Length - 2);
|
|
428 }
|
|
429 }
|
|
430 }
|
|
431
|
|
432 if (word.Length >= 3)
|
|
433 {
|
|
434 switch (word.Substring(word.Length - 3))
|
|
435 {
|
|
436 //box--boxes
|
|
437 case "ses":
|
|
438 //NOTE some false positives here - For words that end in -is, change the -is to -es to make the plural form.
|
|
439 //synopsis--synopses
|
|
440 //thesis--theses
|
|
441 case "zes":
|
|
442 case "xes":
|
|
443 {
|
|
444 return word.Substring(0, word.Length - 2);
|
|
445 }
|
|
446 }
|
|
447 }
|
|
448
|
|
449 if (word.Length >= 3)
|
|
450 {
|
|
451 switch (word.Substring(word.Length - 2))
|
|
452 {
|
|
453 case "es":
|
|
454 {
|
|
455 return word.Substring(0, word.Length - 1); // + "is";
|
|
456 }
|
|
457 //4. Assume add an -s to form the plural of most words.
|
|
458 default:
|
|
459 {
|
|
460 return word.Substring(0, word.Length - 1);
|
|
461 }
|
|
462 }
|
|
463 }
|
|
464
|
|
465 return word;
|
|
466 }
|
|
467
|
|
468 /// <summary>
|
|
469 /// test if a word is plural
|
|
470 /// </summary>
|
|
471 /// <param name="word">word to test</param>
|
|
472 /// <returns>true if a word is plural</returns>
|
|
473 static public bool TestIsPlural(string word)
|
|
474 {
|
|
475 word = word.ToLower();
|
|
476
|
|
477 if (word.Length <= 2)
|
|
478 {
|
|
479 return false; // not a word that can be made singular if only two letters!
|
|
480 }
|
|
481
|
|
482 if (_dictionary.ContainsValue(word))
|
|
483 {
|
|
484 return true; //it's definitely already a plural
|
|
485 }
|
|
486
|
|
487 if (word.Length >= 4)
|
|
488 {
|
|
489 //1. If the word ends in a consonant plus -y, change the -y into -ie and add an -s to form the plural
|
|
490 // e.g. enemy--enemies baby--babies family--families
|
|
491 switch (word.Substring(word.Length - 4))
|
|
492 {
|
|
493 case "bies":
|
|
494 case "cies":
|
|
495 case "dies":
|
|
496 case "fies":
|
|
497 case "gies":
|
|
498 case "hies":
|
|
499 case "jies":
|
|
500 case "kies":
|
|
501 case "lies":
|
|
502 case "mies":
|
|
503 case "nies":
|
|
504 case "pies":
|
|
505 case "ries":
|
|
506 case "sies":
|
|
507 case "ties":
|
|
508 case "vies":
|
|
509 case "wies":
|
|
510 case "xies":
|
|
511 case "zies":
|
|
512 case "ches":
|
|
513 case "shes":
|
|
514 {
|
|
515 return true;
|
|
516 }
|
|
517 }
|
|
518 }
|
|
519
|
|
520 if (word.Length >= 3)
|
|
521 {
|
|
522 switch (word.Substring(word.Length - 3))
|
|
523 {
|
|
524 //box--boxes
|
|
525 case "ses":
|
|
526 case "zes":
|
|
527 case "xes":
|
|
528 {
|
|
529 return true;
|
|
530 }
|
|
531 }
|
|
532 }
|
|
533
|
|
534 if (word.Length >= 3)
|
|
535 {
|
|
536 switch (word.Substring(word.Length - 2))
|
|
537 {
|
|
538 case "es":
|
|
539 {
|
|
540 return true;
|
|
541 }
|
|
542 }
|
|
543 }
|
|
544
|
|
545 if (word.Substring(word.Length - 1) != "s")
|
|
546 {
|
|
547 return false; // not a plural word if it doesn't end in S
|
|
548 }
|
|
549
|
|
550 return true;
|
|
551 }
|
|
552
|
|
553 #endregion
|
|
554 }
|
|
555
|
|
556 #> |