123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- using UnityEngine;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Linq;
- namespace I2.Loc
- {
- using TranslationDictionary = Dictionary<string, TranslationQuery>;
- public struct TranslationQuery
- {
- public string OrigText;
- public string Text; // Text without Tags
- public string LanguageCode;
- public string[] TargetLanguagesCode;
- public string[] Results; // This is filled google returns the translations
- public string[] Tags; // This are the sections of the orignal text that shoudn't be translated
- }
- public static partial class GoogleTranslation
- {
- public static void CreateQueries(string text, string LanguageCodeFrom, string LanguageCodeTo, TranslationDictionary dict)
- {
- if (!text.Contains("[i2s_"))
- {
- CreateQueries_Plurals(text, LanguageCodeFrom, LanguageCodeTo, dict);
- return;
- }
- var variants = SpecializationManager.GetSpecializations(text);
- foreach (var kvp in variants)
- {
- CreateQueries_Plurals(kvp.Value, LanguageCodeFrom, LanguageCodeTo, dict);
- }
- }
- static void CreateQueries_Plurals(string text, string LanguageCodeFrom, string LanguageCodeTo, TranslationDictionary dict)
- {
- bool hasPluralParams = text.Contains("{[#");
- bool hasPluralTypes = text.Contains("[i2p_");
- if (!HasParameters(text) || (!hasPluralParams && !hasPluralTypes))
- {
- AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dict);
- return;
- }
- bool forcePluralParam = hasPluralParams;
- for (var i = (ePluralType)0; i <= ePluralType.Plural; ++i)
- {
- var pluralType = i.ToString();
- if (!GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, pluralType))
- continue;
- var newText = GetPluralText(text, pluralType);
- int testNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, i);
- var parameter = GetPluralParameter(newText, forcePluralParam);
- if (!string.IsNullOrEmpty(parameter))
- newText = newText.Replace(parameter, testNumber.ToString());
- //Debug.Log("Translate: " + newText);
- AddQuery(newText, LanguageCodeFrom, LanguageCodeTo, dict);
- }
- }
- public static void AddQuery(string text, string LanguageCodeFrom, string LanguageCodeTo, TranslationDictionary dict)
- {
- if (string.IsNullOrEmpty(text))
- return;
- if (!dict.ContainsKey(text))
- {
- var query = new TranslationQuery() { OrigText = text, LanguageCode = LanguageCodeFrom, TargetLanguagesCode = new string[] { LanguageCodeTo } };
- query.Text = text;
- ParseNonTranslatableElements(ref query);
- dict[text] = query;
- }
- else
- {
- var query = dict[text];
- if (System.Array.IndexOf(query.TargetLanguagesCode, LanguageCodeTo) < 0)
- {
- query.TargetLanguagesCode = query.TargetLanguagesCode.Concat(new string[] { LanguageCodeTo }).Distinct().ToArray();
- }
- dict[text] = query;
- }
- }
- static string GetTranslation(string text, string LanguageCodeTo, TranslationDictionary dict)
- {
- if (!dict.ContainsKey(text))
- return null;
- var query = dict[text];
- int langIdx = System.Array.IndexOf(query.TargetLanguagesCode, LanguageCodeTo);
- if (langIdx < 0)
- return "";
- if (query.Results == null)
- return "";
- return query.Results[langIdx];
- }
- static TranslationQuery FindQueryFromOrigText(string origText, TranslationDictionary dict)
- {
- foreach (var kvp in dict)
- {
- if (kvp.Value.OrigText == origText)
- return kvp.Value;
- }
- return default(TranslationQuery);
- }
- public static bool HasParameters( string text )
- {
- int idx = text.IndexOf("{[");
- if (idx < 0) return false;
- return text.IndexOf("]}", idx) > 0;
- }
- public static string GetPluralParameter(string text, bool forceTag) // force tag requires that the parameter has the form {[#param]}
- {
- // Try finding the "plural parameter" that has the form {[#name]}
- // this allows using the second parameter as plural: "Player {[name1]} has {[#value]} points"
- int idx0 = text.IndexOf("{[#");
- if (idx0 < 0)
- {
- if (forceTag) return null;
- idx0 = text.IndexOf("{["); // fallback to the first paremeter if no one has the # tag
- }
- if (idx0 < 0)
- return null;
- int idx1 = text.IndexOf("]}", idx0+2);
- if (idx1 < 0)
- return null; // no closing parameter tag
- return text.Substring(idx0, idx1 - idx0 + 2);
- }
- public static string GetPluralText( string text, string pluralType )
- {
- pluralType = "[i2p_" + pluralType + "]";
- int idx0 = text.IndexOf(pluralType);
- if (idx0>=0)
- {
- idx0 += pluralType.Length;
- int idx1 = text.IndexOf("[i2p_",idx0);
- if (idx1 < 0) idx1 = text.Length;
- return text.Substring(idx0, idx1 - idx0);
- }
- // PluralType not found, fallback to the first one
- idx0 = text.IndexOf("[i2p_");
- if (idx0 < 0)
- return text; // No plural tags: "my text"
- if (idx0>0)
- return text.Substring(0, idx0); // Case: "my text[i2p_zero]hello"
- // Case: "[i2p_plural]my text[i2p_zero]hello"
- idx0 = text.IndexOf("]");
- if (idx0 < 0) return text; // starts like a plural, but has none
- idx0 += 1;
- int idx2 = text.IndexOf("[i2p_", idx0);
- if (idx2 < 0) idx2 = text.Length;
- return text.Substring(idx0, idx2 - idx0);
- }
-
- static int FindClosingTag(string tag, MatchCollection matches, int startIndex)
- {
- for (int i = startIndex, imax = matches.Count; i < imax; ++i)
- {
- var newTag = I2Utils.GetCaptureMatch(matches[i]);
- if (newTag[0]=='/' && tag.StartsWith(newTag.Substring(1)))
- return i;
- }
- return -1;
- }
- static string GetGoogleNoTranslateTag(int tagNumber)
- {
- //return " I2NT" + tagNumber;
- if (tagNumber < 70)
- return "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++".Substring(0, tagNumber+1);
- string s = "";
- for (int i = -1; i < tagNumber; ++i)
- s += "+";
- return s;
- }
- static void ParseNonTranslatableElements( ref TranslationQuery query )
- {
- //\[i2nt].*\[\/i2nt]
- var matches = Regex.Matches( query.Text, @"\{\[(.*?)]}|\[(.*?)]|\<(.*?)>");
- if (matches == null || matches.Count == 0)
- return;
- string finalText = query.Text;
- List<string> finalTags = new List<string>();
- for (int i=0, imax=matches.Count; i<imax; ++i)
- {
- var tag = I2Utils.GetCaptureMatch( matches[i] );
- int iClosingTag = FindClosingTag(tag, matches, i); // find [/tag] or </tag>
- if (iClosingTag < 0)
- {
- // Its not a tag, its a parameter
- var fulltag = matches[i].ToString();
- if (fulltag.StartsWith("{[") && fulltag.EndsWith("]}"))
- {
- finalText = finalText.Replace(fulltag, GetGoogleNoTranslateTag(finalTags.Count)+" "); // 0x2600 is the start of the UNICODE Miscellaneous Symbols table, so they are not going to be translated by google
- //finalText = finalText.Replace(fulltag, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString()); // 0x2600 is the start of the UNICODE Miscellaneous Symbols table, so they are not going to be translated by google
- finalTags.Add(fulltag);
- }
- continue;
- }
- if (tag == "i2nt")
- {
- var tag1 = query.Text.Substring(matches[i].Index, (matches[iClosingTag].Index-matches[i].Index) + matches[iClosingTag].Length);
- finalText = finalText.Replace(tag1, GetGoogleNoTranslateTag(finalTags.Count)+" ");
- //finalText = finalText.Replace(tag1, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString());
-
- finalTags.Add(tag1);
- }
- else
- {
- var tag1 = matches[i].ToString();
- finalText = finalText.Replace(tag1, GetGoogleNoTranslateTag(finalTags.Count)+" ");
- //finalText = finalText.Replace(tag1, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString());
- finalTags.Add(tag1);
- var tag2 = matches[iClosingTag].ToString();
- finalText = finalText.Replace(tag2, GetGoogleNoTranslateTag(finalTags.Count)+" ");
- //finalText = finalText.Replace(tag2, /*"{[" + finalTags.Count + "]}"*/ ((char)(0x2600 + finalTags.Count)).ToString());
- finalTags.Add(tag2);
- }
- }
- query.Text = finalText;
- query.Tags = finalTags.ToArray();
- }
- public static string GetQueryResult(string text, string LanguageCodeTo, TranslationDictionary dict)
- {
- if (!dict.ContainsKey(text))
- return null;
- var query = dict[text];
- if (query.Results == null || query.Results.Length < 0)
- return null;
- if (string.IsNullOrEmpty(LanguageCodeTo))
- return query.Results[0];
- int idx = System.Array.IndexOf(query.TargetLanguagesCode, LanguageCodeTo);
- if (idx < 0)
- return null;
- return query.Results[idx];
- }
- public static string RebuildTranslation(string text, TranslationDictionary dict, string LanguageCodeTo)
- {
- if (!text.Contains("[i2s_"))
- {
- return RebuildTranslation_Plural(text, dict, LanguageCodeTo);
- }
- var variants = SpecializationManager.GetSpecializations(text);
- var results = new Dictionary<string,string>();
- foreach (var kvp in variants)
- {
- results[kvp.Key] = RebuildTranslation_Plural(kvp.Value, dict, LanguageCodeTo);
- }
- return SpecializationManager.SetSpecializedText(results);
- }
- static string RebuildTranslation_Plural( string text, TranslationDictionary dict, string LanguageCodeTo )
- {
- bool hasPluralParams = text.Contains("{[#");
- bool hasPluralTypes = text.Contains("[i2p_");
- if (!HasParameters(text) || (!hasPluralParams && !hasPluralTypes))
- {
- return GetTranslation (text, LanguageCodeTo, dict);
- }
- var sb = new System.Text.StringBuilder();
- string pluralTranslation = null;
- bool forcePluralParam = hasPluralParams;
- for (var i = ePluralType.Plural; i >= (ePluralType)0; --i)
- {
- var pluralType = i.ToString();
- if (!GoogleLanguages.LanguageHasPluralType(LanguageCodeTo, pluralType))
- continue;
- var newText = GetPluralText(text, pluralType);
- int testNumber = GoogleLanguages.GetPluralTestNumber(LanguageCodeTo, i);
- var parameter = GetPluralParameter(newText, forcePluralParam);
- if (!string.IsNullOrEmpty(parameter))
- newText = newText.Replace(parameter, testNumber.ToString());
- var translation = GetTranslation(newText, LanguageCodeTo, dict);
- //Debug.LogFormat("from: {0} -> {1}", newText, translation);
- if (!string.IsNullOrEmpty(parameter))
- translation = translation.Replace(testNumber.ToString(), parameter);
- if (i==ePluralType.Plural)
- {
- pluralTranslation = translation;
- }
- else
- {
- if (translation == pluralTranslation)
- continue;
- sb.AppendFormat("[i2p_{0}]", pluralType);
- }
- sb.Append(translation);
- }
- return sb.ToString ();
- }
- public static string UppercaseFirst(string s)
- {
- if (string.IsNullOrEmpty(s))
- {
- return string.Empty;
- }
- char[] a = s.ToLower().ToCharArray();
- a[0] = char.ToUpper(a[0]);
- return new string(a);
- }
- public static string TitleCase(string s)
- {
- if (string.IsNullOrEmpty(s))
- {
- return string.Empty;
- }
- #if NETFX_CORE
- var sb = new StringBuilder(s);
- sb[0] = char.ToUpper(sb[0]);
- for (int i = 1, imax=s.Length; i<imax; ++i)
- {
- if (char.IsWhiteSpace(sb[i - 1]))
- sb[i] = char.ToUpper(sb[i]);
- else
- sb[i] = char.ToLower(sb[i]);
- }
- return sb.ToString();
- #else
- return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s);
- #endif
- }
- }
- }
|