Mercurial > pub > bltoolkit
comparison Source/Templates/PluralSingular.ttinclude @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
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 #> |