Skip to content

Instantly share code, notes, and snippets.

@jammykam
Created February 3, 2015 23:30
Show Gist options
  • Save jammykam/c1f8c82637c0e71be533 to your computer and use it in GitHub Desktop.
Save jammykam/c1f8c82637c0e71be533 to your computer and use it in GitHub Desktop.
Hedgehog CodeGen - Glass Mapper v3
<#+
public static string TitleCase(string word)
{
string newWord = System.Text.RegularExpressions.Regex.Replace(word, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1+");
newWord = System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase(newWord);
newWord = newWord.Replace("+", "");
return newWord;
}
public static string CamelCase(string word)
{
if (word == null)
{
return "";
}
// Something -> something
// ISomething -> iSomething
// SomethingElse -> somethingElse
// ISomethingElse -> iSomethingElse
string titleCase = TitleCase(word);
return titleCase.Substring(0, 1).ToLower() + titleCase.Substring(1);
}
public static bool IsInterfaceWord(string word)
{
// looks like an interface if... I[A-Z]xxxx
// proper definition is http://msdn.microsoft.com/en-us/library/8bc1fexb(v=VS.71).aspx
return (word.Length > 2 && !word.Contains(" ") && (word[0] == 'I' && char.IsUpper(word, 1) && char.IsLower(word, 2)));
}
public static string AsInterfaceName(string word)
{
// return I[TitleCaseWord]
// something -> ISomething
// Something -> ISomething
// ISomething -> ISomething
string interfaceWord = GetFormattedWord(word, TitleCase);
// Only prefix the word with a 'I' if we don't have a word that already looks like an interface.
if (!IsInterfaceWord(word))
{
interfaceWord = string.Concat("I", interfaceWord);
}
return RemoveUnderscores(interfaceWord);
}
public static string AsClassName(string word)
{
// TitleCase the word
return RemoveUnderscores(GetFormattedWord(word, TitleCase));
}
public static string AsPropertyName(string word, bool pluralize = false)
{
// TitleCase the word and pluralize it
if (pluralize)
return RemoveUnderscores(GetFormattedWord(word, TitleCase, Inflector.Pluralize));
else
return RemoveUnderscores(GetFormattedWord(word, TitleCase));
}
public static string AsFieldName(string word)
{
// return _someParam.
// Note, this isn't MS guideline, but it easier to deal with than using this. everywhere to avoid name collisions
return GetFormattedWord(word, CamelCase, (string s) => "_" + s);
}
/// <summary>
/// Tests whether the words conflicts with reserved or language keywords, and if so, attempts to return
/// valid words that do not conflict. Usually the returned words are only slightly modified to differentiate
/// the identifier from the keyword; for example, the word might be preceded by the underscore ("_") character.
/// </summary>
/// <param name="words">The words.</param>
/// <returns></returns>
public static System.Collections.Generic.IEnumerable<string> AsValidWords(System.Collections.Generic.IEnumerable<string> words)
{
foreach (string word in words)
{
yield return AsValidWord(word);
}
}
/// <summary>
/// Tests whether the word conflicts with reserved or language keywords, and if so, attempts to return a
/// valid word that does not conflict. Usually the returned word is only slightly modified to differentiate
/// the identifier from the keyword; for example, the word might be preceded by the underscore ("_") character.
/// <para>
/// Valid identifiers in C# are defined in the C# Language Specification, item 2.4.2. The rules are very simple:
/// - An identifier must start with a letter or an underscore
/// - After the first character, it may contain numbers, letters, connectors, etc
/// - If the identifier is a keyword, it must be prepended with “@”
/// </para>
/// </summary>
/// <param name="word">The word.</param>
/// <returns>A valid word for the specified word.</returns>
public static string AsValidWord(string word)
{
string identifier = word;
if (identifier == "*")
{
identifier = "Wildcard";
}
//identifier = RemoveDiacritics(identifier);
// C# Identifiers - http://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx
// replace all illegal chars with an '_'
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]");
identifier = regex.Replace(identifier, "_");
//The identifier must start with a character or '_'
if (! (char.IsLetter(identifier, 0) || identifier[0] == '_'))
{
identifier = string.Concat("_", identifier);
}
// fix language specific reserved words
identifier = FixReservedWord(identifier);
// Let's make sure we have a valid name
System.Diagnostics.Debug.Assert(System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(identifier), string.Format("'{0}' is an invalid name for a Template or Field", word));
return identifier;
}
/// <summary>
/// Concatenates all of the <paramref name="words"/> with a '.' separator.
/// <para>Each word is passed through the <c>AsValidWord</c> method ensuring that it is a valid for a namespace segment.</para>
/// <para>Leading, trailing, and more than one consecutive '.' are removed.</para>
/// </summary>
/// <example>
/// This sample shows how to call the <see cref="AsNamespace"/> method.
/// <code>
/// string[] segments = new string[5]{ ".My", "Namespace.", "For", "The...Sample..", "Project."};
/// string ns = segments.AsNamespace();
/// </code>
/// The <c>ns</c> variable would contain "<c>My.Namespace.For.The.Sample.Project</c>".
/// </example>
/// <param name="words">The namespace segments.</param>
/// <returns>A valid string in valid namespace format.</returns>
public static string AsNamespace(System.Collections.Generic.IEnumerable<string> words)
{
System.Collections.Generic.List<string> joinedNamespace = new System.Collections.Generic.List<string>();
foreach (string segment in words)
{
if (segment != null)
{
// split apart any strings with a '.' and remove any consecutive multiple '.'
string[] segments = segment.Split(new char[1] { '.' }, StringSplitOptions.RemoveEmptyEntries);
// being we are making a namespace, make sure the segments are valid
System.Collections.Generic.IEnumerable<string> validSegments = AsValidWords(segments);
joinedNamespace.AddRange(validSegments);
}
}
string ns = string.Join(".", joinedNamespace.ToArray());
return ns;
}
/// <summary>
/// Remplacement des caractères accentués
/// </summary>
/// <param name="s">The string to replace diacritics on.</param>
/// <remarks>A diacritic is a glyph added to a letter, or basic glyph</remarks>
/// <returns></returns>
private static string RemoveDiacritics(string s)
{
string normalizedString = s.Normalize(System.Text.NormalizationForm.FormD);
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
foreach (char c in normalizedString)
{
if (System.Globalization.CharUnicodeInfo.GetUnicodeCategory(c) != System.Globalization.UnicodeCategory.NonSpacingMark)
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
/// <summary>
/// Replaces any underscores with an empty string, for instance User_Defined becomes UserDefined
/// </summary>
/// <param name="word">The string to replace underscores on.</param>
/// <returns>The string without any underscores.</returns>
public static string RemoveUnderscores(string word)
{
return !String.IsNullOrEmpty(word)
? word.Replace("_", "")
: word;
}
/// <summary>
/// Tests whether the word conflicts with reserved or language keywords, and if so, attempts to return a
/// valid word that does not conflict. Usually the returned word is only slightly modified to differentiate
/// the identifier from the keyword; for example, the word might be preceded by the underscore ("_") character.
/// </summary>
/// <param name="word">The word.</param>
/// <returns></returns>
private static string FixReservedWord(string word)
{
// turns keywords into usable words.
// i.e. class -> _class
Microsoft.CSharp.CSharpCodeProvider codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
return codeProvider.CreateValidIdentifier(word);
}
private static string GetFormattedWord(string word, params Func<string, string>[] transformations)
{
string newWord = word;
foreach (var item in transformations)
{
if (item != null)
{
newWord = item(newWord);
}
}
// Now that the basic transforms are done, make sure we have a valid word to use
newWord = AsValidWord(newWord);
return newWord;
}
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment