| 
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 #> |