using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Text; namespace FSO.Common.Rendering.Emoji { public class EmojiProvider { public EmojiDictionary Dict; public EmojiCache Cache; public Random DictRand = new Random(); public Dictionary TranslateShortcuts = new Dictionary() { { "i", "eye" }, { "you", "point_right" }, { "your", "point_right" }, { "you're", "point_right" }, { "me", "relieved: :point_left" }, { "i'm", "relieved: :point_left" }, { "us", "couple" }, { "we", "couple" }, { "our", "couple" }, { "what", "woman_shrugging" }, { "be", "b" }, { "to", "two" }, { "and", "symbols" }, { "that", "point_up" }, { "for", "four" }, { "not", "exclamation" }, { "this", "point_up" }, { "but", "exclamation" }, { "his", "man" }, { "her", "woman" }, { "him", "man" }, { "he", "man" }, { "she", "woman" }, { "from", "postbox" }, { "they", "family_man_woman_girl_boy" }, { "them", "family_man_woman_girl_boy" }, { "or", "thinking" }, { "an", "a" }, { "will", "thinking" }, { "my", "relieved: :point_left" }, { "all", "rainbow_flag" }, { "would", "tree" }, { "so", "woman_shrugging" }, { "out", "outbox_tray" }, { "if", "thinking" }, { "about", "arrows_counterclockwise" }, { "who", "thinking: :family_man_woman_girl_boy" }, { "get", "gift" }, { "which", "woman_shrugging" }, { "go", "door" }, { "when", "watch" }, { "make", "toolbox" }, { "know", "brain" }, { "take", "takeout_box" }, { "into", "arrow_heading_down" }, { "year", "calendar" }, { "because", "woman_shrugging" }, { "hmm", "thinking" }, { "yo", "wave" }, { "hey", "wave" }, { "sup", "wave" }, }; public EmojiProvider(GraphicsDevice gd) { Dict = new EmojiDictionary(); Cache = new EmojiCache(gd); } public string EmojiFromName(string name) { string result; if (Dict.NameToEmojis.TryGetValue(name, out result)) return result; return null; } private string StripPunctuation(string word, out string punctuation) { for (int i=word.Length-1; i>=0; i--) { if (!char.IsPunctuation(word[i])) { punctuation = word.Substring(i + 1); return word.Substring(0, i + 1); } } punctuation = ""; return word; } public string SearchForWordHit(string word) { string direct; if (TranslateShortcuts.TryGetValue(word, out direct)) { return ":" + direct + ":"; } if (Dict.NameToEmojis.TryGetValue(word, out direct)) { return ":" + word + ":"; } List options; if (Dict.KeywordToCandidates.TryGetValue(word, out options)) { return ":" + options[DictRand.Next(options.Count)] + ":"; } return null; } public string TranslateWordToEmoji(string word) { string punctuation; var lower = StripPunctuation(word.ToLowerInvariant(), out punctuation); string result; result = SearchForWordHit(lower); if (result != null) return result + ' ' + punctuation; if (lower.EndsWith("s")) { result = SearchForWordHit(lower.Substring(0, lower.Length-1)); if (result != null) return result + ' ' + punctuation; } if (lower.EndsWith("ing")) { result = SearchForWordHit(lower.Substring(0, lower.Length - 3)); if (result != null) return result + ' ' + punctuation; } return word.Substring(0, lower.Length) + punctuation; } public Tuple GetEmoji(string id) { var rect = Cache.GetEmoji(id); return new Tuple(Cache.EmojiTex, rect); } public string EmojiToBB(string input) { //search through the string for emojis to turn to BBcode int index = 0; int lastColon = -1; var result = new StringBuilder(); while (true) { var nColon = input.IndexOf(':', index); if (nColon == -1) break; if (lastColon == -1) result.Append(input.Substring(index, nColon - index)); //add up to the colon else { //is the string between the two colons an emoji? var emoji = EmojiFromName(input.Substring(lastColon + 1, nColon - (lastColon + 1))); if (emoji == null) { result.Append(":"+input.Substring(index, nColon - index)); //add up to the colon (include the last colon we skipped) } else { result.Append("[emoji=" + emoji + "] "); lastColon = -1; index = nColon + 1; continue; } } index = nColon + 1; lastColon = nColon; } result.Append(((lastColon == -1) ? "" : ":") + input.Substring(index)); return result.ToString(); } public string EmojiTranslate(string input) { //search for replacement candidates for each word in input var words = input.Split(' '); for (int i=0; i 2 && word.StartsWith(":") && word.EndsWith(":")) { //is this already an emoji? if so, skip it var existing = EmojiFromName(word.Substring(1, word.Length-2)); if (existing == null) continue; } words[i] = TranslateWordToEmoji(word); } return String.Join(" ", words); } public string EmojiOnly(string input, int mode) { if (mode == 2) return EmojiTranslate(input); //search through the string for emojis to keep int index = 0; int lastColon = -1; var result = new StringBuilder(); while (true) { var nColon = input.IndexOf(':', index); if (nColon == -1) break; else { //is the string between the two colons an emoji? var name = input.Substring(lastColon + 1, nColon - (lastColon + 1)); var emoji = EmojiFromName(name); if (emoji == null) { } else { result.Append(":" + name + ": "); lastColon = -1; index = nColon + 1; continue; } } index = nColon + 1; lastColon = nColon; } //result.Append(((lastColon == -1) ? "" : ":")); return result.ToString(); } } }