基础内容
必要插件安装 缓动曲线和动画基础 ElementFolder,Track与其次级模块,PathNode重构
This commit is contained in:
648
Assets/I2/Localization/Scripts/Google/GoogleLanguages.cs
Normal file
648
Assets/I2/Localization/Scripts/Google/GoogleLanguages.cs
Normal file
@@ -0,0 +1,648 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
public enum ePluralType { Zero, One, Two, Few, Many, Plural }
|
||||
|
||||
public static class GoogleLanguages
|
||||
{
|
||||
public static string GetLanguageCode(string Filter, bool ShowWarnings = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Filter))
|
||||
return string.Empty;
|
||||
|
||||
string[] Filters = Filter.ToLowerInvariant().Split(" /(),".ToCharArray());
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (LanguageMatchesFilter(kvp.Key, Filters))
|
||||
return kvp.Value.Code;
|
||||
|
||||
if (ShowWarnings)
|
||||
Debug.Log($"Language '{Filter}' not recognized. Please, add the language code to GoogleTranslation.cs");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public static List<string> GetLanguagesForDropdown(string Filter, string CodesToExclude)
|
||||
{
|
||||
string[] Filters = Filter.ToLowerInvariant().Split(" /(),".ToCharArray());
|
||||
|
||||
List<string> Languages = new List<string>();
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (string.IsNullOrEmpty(Filter) || LanguageMatchesFilter(kvp.Key, Filters))
|
||||
{
|
||||
string code = string.Concat("[" + kvp.Value.Code + "]");
|
||||
if (!CodesToExclude.Contains(code))
|
||||
Languages.Add(kvp.Key + " " + code);
|
||||
}
|
||||
|
||||
// Add headers to variants (e.g. "English/English" before all English variants
|
||||
for (int i = Languages.Count - 2; i >= 0; --i)
|
||||
{
|
||||
string Prefix = Languages[i].Substring(0, Languages[i].IndexOf(" ["));
|
||||
if (Languages[i + 1].StartsWith(Prefix, StringComparison.Ordinal))
|
||||
{
|
||||
Languages[i] = Prefix + "/" + Languages[i];
|
||||
Languages.Insert(i + 1, Prefix + "/");
|
||||
}
|
||||
}
|
||||
return Languages;
|
||||
}
|
||||
|
||||
// "Engl Unit" matches "English/United States"
|
||||
static bool LanguageMatchesFilter(string Language, string[] Filters)
|
||||
{
|
||||
Language = Language.ToLowerInvariant();
|
||||
for (int i = 0, imax = Filters.Length; i < imax; ++i)
|
||||
if (Filters[i] != "")
|
||||
{
|
||||
if (!Language.Contains(Filters[i].ToLower()))
|
||||
return false;
|
||||
Language = Language.Remove(Language.IndexOf(Filters[i], StringComparison.Ordinal), Filters[i].Length);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// "Arabic/Algeria [ar-XX]" returns "Arabic (Algeria)"
|
||||
// "English/English [en]" returns "English"
|
||||
public static string GetFormatedLanguageName(string Language)
|
||||
{
|
||||
string BaseLanguage = string.Empty;
|
||||
|
||||
//-- Remove code --------
|
||||
int Index = Language.IndexOf(" [", StringComparison.Ordinal);
|
||||
if (Index > 0)
|
||||
Language = Language.Substring(0, Index);
|
||||
|
||||
//-- Check for main language: "English/English [en]" returns "English" -----------
|
||||
Index = Language.IndexOf('/');
|
||||
if (Index > 0)
|
||||
{
|
||||
BaseLanguage = Language.Substring(0, Index);
|
||||
if (Language == BaseLanguage + "/" + BaseLanguage)
|
||||
return BaseLanguage;
|
||||
|
||||
//-- Convert variants into right format
|
||||
Language = Language.Replace("/", " (") + ")";
|
||||
}
|
||||
|
||||
return Language;
|
||||
}
|
||||
|
||||
// English British -> "English Canada [en-CA]"
|
||||
public static string GetCodedLanguage(string Language, string code)
|
||||
{
|
||||
string DefaultCode = GetLanguageCode(Language);
|
||||
if (string.Compare(code, DefaultCode, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
return Language;
|
||||
return string.Concat(Language, " [", code, "]");
|
||||
}
|
||||
|
||||
// "English Canada [en-CA]" -> "English Canada", "en-CA"
|
||||
public static void UnPackCodeFromLanguageName(string CodedLanguage, out string Language, out string code)
|
||||
{
|
||||
if (string.IsNullOrEmpty(CodedLanguage))
|
||||
{
|
||||
Language = string.Empty;
|
||||
code = string.Empty;
|
||||
return;
|
||||
}
|
||||
int Index = CodedLanguage.IndexOf("[", StringComparison.Ordinal);
|
||||
if (Index < 0)
|
||||
{
|
||||
Language = CodedLanguage;
|
||||
code = GetLanguageCode(Language);
|
||||
}
|
||||
else
|
||||
{
|
||||
Language = CodedLanguage.Substring(0, Index).Trim();
|
||||
code = CodedLanguage.Substring(Index + 1, CodedLanguage.IndexOf("]", Index, StringComparison.Ordinal) - Index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetGoogleLanguageCode(string InternationalCode)
|
||||
{
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (InternationalCode == kvp.Value.Code)
|
||||
{
|
||||
if (kvp.Value.GoogleCode == "-")
|
||||
return null;
|
||||
return !string.IsNullOrEmpty(kvp.Value.GoogleCode) ? kvp.Value.GoogleCode : InternationalCode;
|
||||
}
|
||||
|
||||
return InternationalCode;
|
||||
}
|
||||
|
||||
public static string GetLanguageName(string code, bool useParenthesesForRegion=false, bool allowDiscardRegion=true)
|
||||
{
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (code == kvp.Value.Code)
|
||||
{
|
||||
var langName = kvp.Key;
|
||||
if (useParenthesesForRegion)
|
||||
{
|
||||
int idx = langName.IndexOf('/');
|
||||
if (idx > 0)
|
||||
langName = langName.Substring(0, idx) + " (" + langName.Substring(idx + 1) + ")";
|
||||
}
|
||||
return langName;
|
||||
}
|
||||
|
||||
if (allowDiscardRegion)
|
||||
{
|
||||
int iCode = code.IndexOf("-", StringComparison.Ordinal);
|
||||
if (iCode > 0)
|
||||
return GetLanguageName(code.Substring(0,iCode), useParenthesesForRegion, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<string> GetAllInternationalCodes()
|
||||
{
|
||||
var set = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
set.Add(kvp.Value.Code);
|
||||
|
||||
return new List<string>(set);
|
||||
}
|
||||
|
||||
public static bool LanguageCode_HasJoinedWord(string languageCode)
|
||||
{
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (languageCode == kvp.Value.GoogleCode || languageCode==kvp.Value.Code )
|
||||
return kvp.Value.HasJoinedWords;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public struct LanguageCodeDef
|
||||
{
|
||||
public string Code; // Language International Code
|
||||
public string GoogleCode; // Google Translator doesn't support all languages, this is the code of closest supported language
|
||||
public bool HasJoinedWords; // Some languages (e.g. Chinese, Japanese and Thai) don't add spaces to their words (all characters are placed toguether)
|
||||
public int PluralRule;
|
||||
}
|
||||
|
||||
public static Dictionary<string, LanguageCodeDef> mLanguageDef = new Dictionary<string, LanguageCodeDef>(StringComparer.Ordinal)
|
||||
{
|
||||
/**/{"Abkhazian", new LanguageCodeDef {PluralRule=1, Code="ab", GoogleCode="-"}},
|
||||
/**/{"Afar", new LanguageCodeDef {PluralRule=1, Code="aa", GoogleCode="-"}},
|
||||
{"Afrikaans", new LanguageCodeDef {PluralRule=1, Code="af"}},
|
||||
/**/{"Akan", new LanguageCodeDef {PluralRule=1, Code="ak", GoogleCode="-"}},
|
||||
{"Albanian", new LanguageCodeDef {PluralRule=1, Code="sq"}},
|
||||
/**/{"Amharic", new LanguageCodeDef {PluralRule=1, Code="am"}},
|
||||
{"Arabic", new LanguageCodeDef {PluralRule=11, Code="ar"}},
|
||||
{"Arabic/Algeria", new LanguageCodeDef {PluralRule=11, Code="ar-DZ", GoogleCode="ar"}},
|
||||
{"Arabic/Bahrain", new LanguageCodeDef {PluralRule=11, Code="ar-BH", GoogleCode="ar"}},
|
||||
{"Arabic/Egypt", new LanguageCodeDef {PluralRule=11, Code="ar-EG", GoogleCode="ar"}},
|
||||
{"Arabic/Iraq", new LanguageCodeDef {PluralRule=11, Code="ar-IQ", GoogleCode="ar"}},
|
||||
{"Arabic/Jordan", new LanguageCodeDef {PluralRule=11, Code="ar-JO", GoogleCode="ar"}},
|
||||
{"Arabic/Kuwait", new LanguageCodeDef {PluralRule=11, Code="ar-KW", GoogleCode="ar"}},
|
||||
{"Arabic/Lebanon", new LanguageCodeDef {PluralRule=11, Code="ar-LB", GoogleCode="ar"}},
|
||||
{"Arabic/Libya", new LanguageCodeDef {PluralRule=11, Code="ar-LY", GoogleCode="ar"}},
|
||||
{"Arabic/Morocco", new LanguageCodeDef {PluralRule=11, Code="ar-MA", GoogleCode="ar"}},
|
||||
{"Arabic/Oman", new LanguageCodeDef {PluralRule=11, Code="ar-OM", GoogleCode="ar"}},
|
||||
{"Arabic/Qatar", new LanguageCodeDef {PluralRule=11, Code="ar-QA", GoogleCode="ar"}},
|
||||
{"Arabic/Saudi Arabia", new LanguageCodeDef {PluralRule=11, Code="ar-SA", GoogleCode="ar"}},
|
||||
{"Arabic/Syria", new LanguageCodeDef {PluralRule=11, Code="ar-SY", GoogleCode="ar"}},
|
||||
{"Arabic/Tunisia", new LanguageCodeDef {PluralRule=11, Code="ar-TN", GoogleCode="ar"}},
|
||||
{"Arabic/U.A.E.", new LanguageCodeDef {PluralRule=11, Code="ar-AE", GoogleCode="ar"}},
|
||||
{"Arabic/Yemen", new LanguageCodeDef {PluralRule=11, Code="ar-YE", GoogleCode="ar"}},
|
||||
/**/{"Aragonese", new LanguageCodeDef {PluralRule=1, Code="an", GoogleCode="-"}},
|
||||
{"Armenian", new LanguageCodeDef {PluralRule=1, Code="hy"}},
|
||||
/**/{"Assamese", new LanguageCodeDef {PluralRule=1, Code="as", GoogleCode="-"}},
|
||||
/**/{"Avaric", new LanguageCodeDef {PluralRule=1, Code="av", GoogleCode="-"}},
|
||||
/**/{"Avestan", new LanguageCodeDef {PluralRule=1, Code="ae", GoogleCode="-"}},
|
||||
/**/{"Aymara", new LanguageCodeDef {PluralRule=1, Code="ay", GoogleCode="-"}},
|
||||
{"Azerbaijani", new LanguageCodeDef {PluralRule=1, Code="az"}},
|
||||
/**/{"Bambara", new LanguageCodeDef {PluralRule=1, Code="bm", GoogleCode="-"}},
|
||||
/**/{"Bashkir", new LanguageCodeDef {PluralRule=1, Code="ba", GoogleCode="-"}},
|
||||
{"Basque", new LanguageCodeDef {PluralRule=1, Code="eu"}},
|
||||
{"Basque/Spain", new LanguageCodeDef {PluralRule=1, Code="eu-ES", GoogleCode="eu"}},
|
||||
{"Belarusian", new LanguageCodeDef {PluralRule=6, Code="be"}},
|
||||
/**/{"Bengali", new LanguageCodeDef {PluralRule=1, Code="bn"}},
|
||||
/**/{"Bihari", new LanguageCodeDef {PluralRule=1, Code="bh", GoogleCode="-"}},
|
||||
/**/{"Bislama", new LanguageCodeDef {PluralRule=1, Code="bi", GoogleCode="-"}},
|
||||
{"Bosnian", new LanguageCodeDef {PluralRule=6, Code="bs"}},
|
||||
/**/{"Breton", new LanguageCodeDef {PluralRule=1, Code="br", GoogleCode="-"}},
|
||||
{"Bulgariaa", new LanguageCodeDef {PluralRule=1, Code="bg"}},
|
||||
/**/{"Burmese", new LanguageCodeDef {PluralRule=1, Code="my"}},
|
||||
{"Catalan", new LanguageCodeDef {PluralRule=1, Code="ca"}},
|
||||
/**/{"Chamorro", new LanguageCodeDef {PluralRule=1, Code="ch", GoogleCode="-"}},
|
||||
/**/{"Chechen", new LanguageCodeDef {PluralRule=1, Code="ce", GoogleCode="-"}},
|
||||
/**/{"Chichewa", new LanguageCodeDef {PluralRule=1, Code="ny"}},
|
||||
{"Chinese", new LanguageCodeDef {PluralRule=0, Code="zh", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Hong Kong", new LanguageCodeDef {PluralRule=0, Code="zh-HK", GoogleCode="zh-TW", HasJoinedWords=true}},
|
||||
{"Chinese/Macau", new LanguageCodeDef {PluralRule=0, Code="zh-MO", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/PRC", new LanguageCodeDef {PluralRule=0, Code="zh-CN", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Simplified", new LanguageCodeDef {PluralRule=0, Code="zh-CN", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Singapore", new LanguageCodeDef {PluralRule=0, Code="zh-SG", GoogleCode="zh-CN", HasJoinedWords=true}},
|
||||
{"Chinese/Taiwan", new LanguageCodeDef {PluralRule=0, Code="zh-TW", GoogleCode="zh-TW", HasJoinedWords=true}},
|
||||
{"Chinese/Traditional", new LanguageCodeDef {PluralRule=0, Code="zh-TW", GoogleCode="zh-TW", HasJoinedWords=true}},
|
||||
/**/{"Chuvash", new LanguageCodeDef {PluralRule=1, Code="cv", GoogleCode="-"}},
|
||||
/**/{"Cornish", new LanguageCodeDef {PluralRule=1, Code="kw", GoogleCode="-"}}, // Check plural
|
||||
/**/{"Corsican", new LanguageCodeDef {PluralRule=1, Code="co"}},
|
||||
/**/{"Cree", new LanguageCodeDef {PluralRule=1, Code="cr", GoogleCode="-"}},
|
||||
{"Croatian", new LanguageCodeDef {PluralRule=6, Code="hr"}},
|
||||
{"Croatian/Bosnia and Herzegovina", new LanguageCodeDef {PluralRule=5, Code="hr-BA", GoogleCode="hr"}},
|
||||
{"Czech", new LanguageCodeDef {PluralRule=7, Code="cs"}},
|
||||
{"Danish", new LanguageCodeDef {PluralRule=1, Code="da"}},
|
||||
/**/{"Divehi", new LanguageCodeDef {PluralRule=1, Code="dv", GoogleCode="-"}},
|
||||
{"Dutch", new LanguageCodeDef {PluralRule=1, Code="nl"}},
|
||||
{"Dutch/Belgium", new LanguageCodeDef {PluralRule=1, Code="nl-BE", GoogleCode="nl"}},
|
||||
{"Dutch/Netherlands", new LanguageCodeDef {PluralRule=1, Code="nl-NL", GoogleCode="nl"}},
|
||||
/**/{"Dzongkha", new LanguageCodeDef {PluralRule=1, Code="dz", GoogleCode="-"}},
|
||||
{"English", new LanguageCodeDef {PluralRule=1, Code="en"}},
|
||||
{"English/Australia", new LanguageCodeDef {PluralRule=1, Code="en-AU", GoogleCode="en"}},
|
||||
{"English/Belize", new LanguageCodeDef {PluralRule=1, Code="en-BZ", GoogleCode="en"}},
|
||||
{"English/Canada", new LanguageCodeDef {PluralRule=1, Code="en-CA", GoogleCode="en"}},
|
||||
{"English/Caribbean", new LanguageCodeDef {PluralRule=1, Code="en-CB", GoogleCode="en"}},
|
||||
{"English/Ireland", new LanguageCodeDef {PluralRule=1, Code="en-IE", GoogleCode="en"}},
|
||||
{"English/Jamaica", new LanguageCodeDef {PluralRule=1, Code="en-JM", GoogleCode="en"}},
|
||||
{"English/New Zealand", new LanguageCodeDef {PluralRule=1, Code="en-NZ", GoogleCode="en"}},
|
||||
{"English/Republic of the Philippines", new LanguageCodeDef {PluralRule=1, Code="en-PH", GoogleCode="en"}},
|
||||
{"English/South Africa",new LanguageCodeDef {PluralRule=1, Code="en-ZA", GoogleCode="en"}},
|
||||
{"English/Trinidad", new LanguageCodeDef {PluralRule=1, Code="en-TT", GoogleCode="en"}},
|
||||
{"English/United Kingdom",new LanguageCodeDef {PluralRule=1, Code="en-GB", GoogleCode="en"}},
|
||||
{"English/United States",new LanguageCodeDef {PluralRule=1, Code="en-US", GoogleCode="en"}},
|
||||
{"English/Zimbabwe", new LanguageCodeDef {PluralRule=1, Code="en-ZW", GoogleCode="en"}},
|
||||
{"Esperanto", new LanguageCodeDef {PluralRule=1, Code="eo"}},
|
||||
{"Estonian", new LanguageCodeDef {PluralRule=1, Code="et"}},
|
||||
/**/{"Ewe", new LanguageCodeDef {PluralRule=1, Code="ee", GoogleCode="-"}},
|
||||
{"Faeroese", new LanguageCodeDef {PluralRule=1, Code="fo", GoogleCode="-"}},
|
||||
/**/{"Fijian", new LanguageCodeDef {PluralRule=1, Code="fj", GoogleCode="-"}},
|
||||
//{"Filipino", new LanguageCodeDef(){PluralRule=2, Code="tl"}},
|
||||
{"Finnish", new LanguageCodeDef {PluralRule=1, Code="fi"}},
|
||||
{"French", new LanguageCodeDef {PluralRule=2, Code="fr"}},
|
||||
{"French/Belgium", new LanguageCodeDef {PluralRule=2, Code="fr-BE", GoogleCode="fr"}},
|
||||
{"French/Canada", new LanguageCodeDef {PluralRule=2, Code="fr-CA", GoogleCode="fr"}},
|
||||
{"French/France", new LanguageCodeDef {PluralRule=2, Code="fr-FR", GoogleCode="fr"}},
|
||||
{"French/Luxembourg", new LanguageCodeDef {PluralRule=2, Code="fr-LU", GoogleCode="fr"}},
|
||||
{"French/Principality of Monaco", new LanguageCodeDef {PluralRule=2, Code="fr-MC", GoogleCode="fr"}},
|
||||
{"French/Switzerland", new LanguageCodeDef {PluralRule=2, Code="fr-CH", GoogleCode="fr"}},
|
||||
/**/{"Fulah", new LanguageCodeDef {PluralRule=1, Code="ff", GoogleCode="-"}},
|
||||
{"Galician", new LanguageCodeDef {PluralRule=1, Code="gl"}},
|
||||
{"Galician/Spain", new LanguageCodeDef {PluralRule=1, Code="gl-ES", GoogleCode="gl"}},
|
||||
{"Georgian", new LanguageCodeDef {PluralRule=0, Code="ka"}},
|
||||
{"German", new LanguageCodeDef {PluralRule=1, Code="de"}},
|
||||
{"German/Austria", new LanguageCodeDef {PluralRule=1, Code="de-AT", GoogleCode="de"}},
|
||||
{"German/Germany", new LanguageCodeDef {PluralRule=1, Code="de-DE", GoogleCode="de"}},
|
||||
{"German/Liechtenstein",new LanguageCodeDef {PluralRule=1, Code="de-LI", GoogleCode="de"}},
|
||||
{"German/Luxembourg", new LanguageCodeDef {PluralRule=1, Code="de-LU", GoogleCode="de"}},
|
||||
{"German/Switzerland", new LanguageCodeDef {PluralRule=1, Code="de-CH", GoogleCode="de"}},
|
||||
{"Greek", new LanguageCodeDef {PluralRule=1, Code="el"}},
|
||||
/**/{"Guaraní", new LanguageCodeDef {PluralRule=1, Code="gn", GoogleCode="-"}},
|
||||
{"Gujarati", new LanguageCodeDef {PluralRule=1, Code="gu"}},
|
||||
/**/{"Haitian", new LanguageCodeDef {PluralRule=1, Code="ht"}},
|
||||
/**/{"Hausa", new LanguageCodeDef {PluralRule=1, Code="ha"}},
|
||||
{"Hebrew", new LanguageCodeDef {PluralRule=1, Code="he", GoogleCode="iw"}},
|
||||
/**/{"Herero", new LanguageCodeDef {PluralRule=1, Code="hz", GoogleCode="-"}},
|
||||
{"Hindi", new LanguageCodeDef {PluralRule=1, Code="hi"}},
|
||||
/**/{"Hiri Motu", new LanguageCodeDef {PluralRule=1, Code="ho", GoogleCode="-"}},
|
||||
{"Hungarian", new LanguageCodeDef {PluralRule=1, Code="hu"}},
|
||||
/**/{"Interlingua", new LanguageCodeDef {PluralRule=1, Code="ia", GoogleCode="-"}},
|
||||
{"Indonesian", new LanguageCodeDef {PluralRule=0, Code="id"}},
|
||||
/**/{"Interlingue", new LanguageCodeDef {PluralRule=1, Code="ie", GoogleCode="-"}},
|
||||
{"Irish", new LanguageCodeDef {PluralRule=10, Code="ga"}},
|
||||
/**/{"Igbo", new LanguageCodeDef {PluralRule=1, Code="ig"}},
|
||||
/**/{"Inupiaq", new LanguageCodeDef {PluralRule=1, Code="ik", GoogleCode="-"}},
|
||||
/**/{"Ido", new LanguageCodeDef {PluralRule=1, Code="io", GoogleCode="-"}},
|
||||
{"Icelandic", new LanguageCodeDef {PluralRule=14, Code="is"}},
|
||||
{"Italian", new LanguageCodeDef {PluralRule=1, Code="it"}},
|
||||
{"Italian/Italy", new LanguageCodeDef {PluralRule=1, Code="it-IT", GoogleCode="it"}},
|
||||
{"Italian/Switzerland", new LanguageCodeDef {PluralRule=1, Code="it-CH", GoogleCode="it"}},
|
||||
/**/{"Inuktitut", new LanguageCodeDef {PluralRule=1, Code="iu", GoogleCode="-"}},
|
||||
{"Japanese", new LanguageCodeDef {PluralRule=0, Code="ja", HasJoinedWords=true}},
|
||||
/**/{"Javanese", new LanguageCodeDef {PluralRule=1, Code="jv"}},
|
||||
/**/{"Kalaallisut", new LanguageCodeDef {PluralRule=1, Code="kl", GoogleCode="-"}},
|
||||
{"Kannada", new LanguageCodeDef {PluralRule=1, Code="kn"}},
|
||||
/**/{"Kanuri", new LanguageCodeDef {PluralRule=1, Code="kr", GoogleCode="-"}},
|
||||
/**/{"Kashmiri", new LanguageCodeDef {PluralRule=1, Code="ks", GoogleCode="-"}},
|
||||
{"Kazakh", new LanguageCodeDef {PluralRule=1, Code="kk"}},
|
||||
/**/{"Central Khmer", new LanguageCodeDef {PluralRule=1, Code="km"}},
|
||||
/**/{"Kikuyu", new LanguageCodeDef {PluralRule=1, Code="ki", GoogleCode="-"}},
|
||||
/**/{"Kinyarwanda", new LanguageCodeDef {PluralRule=1, Code="rw", GoogleCode="-"}},
|
||||
/**/{"Kirghiz", new LanguageCodeDef {PluralRule=1, Code="ky"}},
|
||||
/**/{"Komi", new LanguageCodeDef {PluralRule=1, Code="kv", GoogleCode="-"}},
|
||||
/**/{"Kongo", new LanguageCodeDef {PluralRule=1, Code="kg", GoogleCode="-"}},
|
||||
{"Korean", new LanguageCodeDef {PluralRule=0, Code="ko"}},
|
||||
{"Kurdish", new LanguageCodeDef {PluralRule=1, Code="ku"}},
|
||||
/**/{"Kuanyama", new LanguageCodeDef {PluralRule=1, Code="kj", GoogleCode="-"}},
|
||||
{"Latin", new LanguageCodeDef {PluralRule=1, Code="la"}},
|
||||
/**/{"Luxembourgish", new LanguageCodeDef {PluralRule=1, Code="lb"}},
|
||||
/**/{"Ganda", new LanguageCodeDef {PluralRule=1, Code="lg", GoogleCode="-"}},
|
||||
/**/{"Limburgan", new LanguageCodeDef {PluralRule=1, Code="li", GoogleCode="-"}},
|
||||
/**/{"Lingala", new LanguageCodeDef {PluralRule=1, Code="ln", GoogleCode="-"}},
|
||||
/**/{"Lao", new LanguageCodeDef {PluralRule=1, Code="lo"}},
|
||||
{"Latvian", new LanguageCodeDef {PluralRule=5, Code="lv"}},
|
||||
/**/{"Luba-Katanga", new LanguageCodeDef {PluralRule=1, Code="lu", GoogleCode="-"}},
|
||||
{"Lithuanian", new LanguageCodeDef {PluralRule=5, Code="lt"}},
|
||||
/**/{"Manx", new LanguageCodeDef {PluralRule=1, Code="gv", GoogleCode="-"}},
|
||||
{"Macedonian", new LanguageCodeDef {PluralRule=13, Code="mk"}},
|
||||
/**/{"Malagasy", new LanguageCodeDef {PluralRule=1, Code="mg"}},
|
||||
{"Malay", new LanguageCodeDef {PluralRule=0, Code="ms"}},
|
||||
{"Malay/Brunei Darussalam", new LanguageCodeDef {PluralRule=0, Code="ms-BN", GoogleCode="ms"}},
|
||||
{"Malay/Malaysia", new LanguageCodeDef {PluralRule=0, Code="ms-MY", GoogleCode="ms"}},
|
||||
{"Malayalam", new LanguageCodeDef {PluralRule=1, Code="ml"}},
|
||||
{"Maltese", new LanguageCodeDef {PluralRule=12, Code="mt"}},
|
||||
{"Maori", new LanguageCodeDef {PluralRule=2, Code="mi"}},
|
||||
{"Marathi", new LanguageCodeDef {PluralRule=1, Code="mr"}},
|
||||
/**/{"Marshallese", new LanguageCodeDef {PluralRule=1, Code="mh", GoogleCode="-"}},
|
||||
{"Mongolian", new LanguageCodeDef {PluralRule=1, Code="mn"}},
|
||||
/**/{"Nauru", new LanguageCodeDef {PluralRule=1, Code="na", GoogleCode="-"}},
|
||||
/**/{"Navajo", new LanguageCodeDef {PluralRule=1, Code="nv", GoogleCode="-"}},
|
||||
/**/{"North Ndebele", new LanguageCodeDef {PluralRule=1, Code="nd", GoogleCode="-"}},
|
||||
/**/{"Nepali", new LanguageCodeDef {PluralRule=1, Code="ne"}},
|
||||
/**/{"Ndonga", new LanguageCodeDef {PluralRule=1, Code="ng", GoogleCode="-"}},
|
||||
{"Northern Sotho", new LanguageCodeDef {PluralRule=1, Code="ns", GoogleCode="st"}},
|
||||
{"Norwegian", new LanguageCodeDef {PluralRule=1, Code="nb", GoogleCode="no"}},
|
||||
{"Norwegian/Nynorsk", new LanguageCodeDef {PluralRule=1, Code="nn", GoogleCode="no"}},
|
||||
/**/{"Sichuan Yi", new LanguageCodeDef {PluralRule=1, Code="ii", GoogleCode="-"}},
|
||||
/**/{"South Ndebele", new LanguageCodeDef {PluralRule=1, Code="nr", GoogleCode="-"}},
|
||||
/**/{"Occitan", new LanguageCodeDef {PluralRule=1, Code="oc", GoogleCode="-"}},
|
||||
/**/{"Ojibwa", new LanguageCodeDef {PluralRule=1, Code="oj", GoogleCode="-"}},
|
||||
/**/{"Church Slavic", new LanguageCodeDef {PluralRule=1, Code="cu", GoogleCode="-"}},
|
||||
/**/{"Oromo", new LanguageCodeDef {PluralRule=1, Code="om", GoogleCode="-"}},
|
||||
/**/{"Oriya", new LanguageCodeDef {PluralRule=1, Code="or", GoogleCode="-"}},
|
||||
/**/{"Ossetian", new LanguageCodeDef {PluralRule=1, Code="os", GoogleCode="-"}},
|
||||
/**/{"Pali", new LanguageCodeDef {PluralRule=1, Code="pi", GoogleCode="-"}},
|
||||
{"Pashto", new LanguageCodeDef {PluralRule=1, Code="ps"}},
|
||||
{"Persian", new LanguageCodeDef {PluralRule=0, Code="fa"}},
|
||||
{"Polish", new LanguageCodeDef {PluralRule=8, Code="pl"}},
|
||||
{"Portuguese", new LanguageCodeDef {PluralRule=1, Code="pt"}},
|
||||
{"Portuguese/Brazil", new LanguageCodeDef {PluralRule=2, Code="pt-BR", GoogleCode="pt"}},
|
||||
{"Portuguese/Portugal", new LanguageCodeDef {PluralRule=1, Code="pt-PT", GoogleCode="pt"}},
|
||||
{"Punjabi", new LanguageCodeDef {PluralRule=1, Code="pa"}},
|
||||
{"Quechua", new LanguageCodeDef {PluralRule=1, Code="qu", GoogleCode="-"}},
|
||||
{"Quechua/Bolivia", new LanguageCodeDef {PluralRule=1, Code="qu-BO", GoogleCode="-"}},
|
||||
{"Quechua/Ecuador", new LanguageCodeDef {PluralRule=1, Code="qu-EC", GoogleCode="-"}},
|
||||
{"Quechua/Peru", new LanguageCodeDef {PluralRule=1, Code="qu-PE", GoogleCode="-"}},
|
||||
{"Rhaeto-Romanic", new LanguageCodeDef {PluralRule=1, Code="rm", GoogleCode="ro"}},
|
||||
{"Romanian", new LanguageCodeDef {PluralRule=4, Code="ro"}},
|
||||
/**/{"Rundi", new LanguageCodeDef {PluralRule=1, Code="rn", GoogleCode="-"}},
|
||||
{"Russian", new LanguageCodeDef {PluralRule=6, Code="ru"}},
|
||||
{"Russian/Republic of Moldova", new LanguageCodeDef {PluralRule=6, Code="ru-MO", GoogleCode="ru"}},
|
||||
/**/{"Sanskrit", new LanguageCodeDef {PluralRule=1, Code="sa", GoogleCode="-"}},
|
||||
/**/{"Sardinian", new LanguageCodeDef {PluralRule=1, Code="sc", GoogleCode="-"}},
|
||||
/**/{"Sindhi", new LanguageCodeDef {PluralRule=1, Code="sd"}},
|
||||
/**/{"Northern Sami", new LanguageCodeDef {PluralRule=1, Code="se", GoogleCode="-"}},
|
||||
/**/{"Samoan", new LanguageCodeDef {PluralRule=1, Code="sm"}},
|
||||
/**/{"Sango", new LanguageCodeDef {PluralRule=1, Code="sg", GoogleCode="-"}},
|
||||
{"Serbian", new LanguageCodeDef {PluralRule=6, Code="sr"}},
|
||||
{"Serbian/Bosnia and Herzegovina", new LanguageCodeDef {PluralRule=5, Code="sr-BA", GoogleCode="sr"}},
|
||||
{"Serbian/Serbia and Montenegro", new LanguageCodeDef {PluralRule=5, Code="sr-SP", GoogleCode="sr"}},
|
||||
/**/{"Scottish Gaelic", new LanguageCodeDef {PluralRule=1, Code="gd"}},
|
||||
/**/{"Shona", new LanguageCodeDef {PluralRule=1, Code="sn"}},
|
||||
/**/{"Sinhala", new LanguageCodeDef {PluralRule=1, Code="si"}},
|
||||
{"Slovak", new LanguageCodeDef {PluralRule=7, Code="sk"}},
|
||||
{"Slovenian", new LanguageCodeDef {PluralRule=9, Code="sl"}},
|
||||
/**/{"Somali", new LanguageCodeDef {PluralRule=1, Code="so"}},
|
||||
/**/{"Southern Sotho", new LanguageCodeDef {PluralRule=1, Code="st"}},
|
||||
{"Spanish", new LanguageCodeDef {PluralRule=1, Code="es"}},
|
||||
{"Spanish/Argentina", new LanguageCodeDef {PluralRule=1, Code="es-AR", GoogleCode="es"}},
|
||||
{"Spanish/Bolivia", new LanguageCodeDef {PluralRule=1, Code="es-BO", GoogleCode="es"}},
|
||||
{"Spanish/Castilian", new LanguageCodeDef {PluralRule=1, Code="es-ES", GoogleCode="es"}},
|
||||
{"Spanish/Chile", new LanguageCodeDef {PluralRule=1, Code="es-CL", GoogleCode="es"}},
|
||||
{"Spanish/Colombia", new LanguageCodeDef {PluralRule=1, Code="es-CO", GoogleCode="es"}},
|
||||
{"Spanish/Costa Rica", new LanguageCodeDef {PluralRule=1, Code="es-CR", GoogleCode="es"}},
|
||||
{"Spanish/Dominican Republic", new LanguageCodeDef {PluralRule=1, Code="es-DO", GoogleCode="es"}},
|
||||
{"Spanish/Ecuador", new LanguageCodeDef {PluralRule=1, Code="es-EC", GoogleCode="es"}},
|
||||
{"Spanish/El Salvador", new LanguageCodeDef {PluralRule=1, Code="es-SV", GoogleCode="es"}},
|
||||
{"Spanish/Guatemala", new LanguageCodeDef {PluralRule=1, Code="es-GT", GoogleCode="es"}},
|
||||
{"Spanish/Honduras", new LanguageCodeDef {PluralRule=1, Code="es-HN", GoogleCode="es"}},
|
||||
{"Spanish/Mexico", new LanguageCodeDef {PluralRule=1, Code="es-MX", GoogleCode="es"}},
|
||||
{"Spanish/Nicaragua", new LanguageCodeDef {PluralRule=1, Code="es-NI", GoogleCode="es"}},
|
||||
{"Spanish/Panama", new LanguageCodeDef {PluralRule=1, Code="es-PA", GoogleCode="es"}},
|
||||
{"Spanish/Paraguay", new LanguageCodeDef {PluralRule=1, Code="es-PY", GoogleCode="es"}},
|
||||
{"Spanish/Peru", new LanguageCodeDef {PluralRule=1, Code="es-PE", GoogleCode="es"}},
|
||||
{"Spanish/Puerto Rico", new LanguageCodeDef {PluralRule=1, Code="es-PR", GoogleCode="es"}},
|
||||
{"Spanish/Spain", new LanguageCodeDef {PluralRule=1, Code="es-ES", GoogleCode="es"}},
|
||||
{"Spanish/Uruguay", new LanguageCodeDef {PluralRule=1, Code="es-UY", GoogleCode="es"}},
|
||||
{"Spanish/Venezuela", new LanguageCodeDef {PluralRule=1, Code="es-VE", GoogleCode="es"}},
|
||||
{"Spanish/Latin Americas", new LanguageCodeDef {PluralRule=1, Code="es-US", GoogleCode="es"}},
|
||||
/**/{"Sundanese", new LanguageCodeDef {PluralRule=1, Code="su"}},
|
||||
{"Swahili", new LanguageCodeDef {Code="sw"}},
|
||||
/**/{"Swati", new LanguageCodeDef {PluralRule=1, Code="ss", GoogleCode="-"}},
|
||||
{"Swedish", new LanguageCodeDef {PluralRule=1, Code="sv"}},
|
||||
{"Swedish/Finland", new LanguageCodeDef {PluralRule=1, Code="sv-FI", GoogleCode="sv"}},
|
||||
{"Swedish/Sweden", new LanguageCodeDef {PluralRule=1, Code="sv-SE", GoogleCode="sv"}},
|
||||
{"Tamil", new LanguageCodeDef {PluralRule=1, Code="ta"}},
|
||||
{"Tatar", new LanguageCodeDef {PluralRule=0, Code="tt", GoogleCode="-"}},
|
||||
{"Telugu", new LanguageCodeDef {PluralRule=1, Code="te"}},
|
||||
/**/{"Tajik", new LanguageCodeDef {PluralRule=1, Code="tg"}},
|
||||
{"Thai", new LanguageCodeDef {PluralRule=0, Code="th", HasJoinedWords=true}},
|
||||
/**/{"Tigrinya", new LanguageCodeDef {PluralRule=1, Code="ti", GoogleCode="-"}},
|
||||
/**/{"Tibetan", new LanguageCodeDef {PluralRule=1, Code="bo", GoogleCode="-"}},
|
||||
/**/{"Turkmen", new LanguageCodeDef {PluralRule=1, Code="tk", GoogleCode="-"}},
|
||||
/**/{"Tagalog", new LanguageCodeDef {PluralRule=1, Code="tl"}},
|
||||
/**/{"Tswana", new LanguageCodeDef {PluralRule=1, Code="tn", GoogleCode="-"}},
|
||||
/**/{"Tonga", new LanguageCodeDef {PluralRule=1, Code="to", GoogleCode="-"}},
|
||||
{"Turkish", new LanguageCodeDef {PluralRule=0, Code="tr"}},
|
||||
/**/{"Tsonga", new LanguageCodeDef {PluralRule=1, Code="ts", GoogleCode="-"}},
|
||||
/**/{"Twi", new LanguageCodeDef {PluralRule=1, Code="tw", GoogleCode="-"}},
|
||||
/**/{"Tahitian", new LanguageCodeDef {PluralRule=1, Code="ty", GoogleCode="-"}},
|
||||
/**/{"Uighur", new LanguageCodeDef {PluralRule=1, Code="ug", GoogleCode="-"}},
|
||||
{"Ukrainian", new LanguageCodeDef {PluralRule=6, Code="uk"}},
|
||||
{"Urdu", new LanguageCodeDef {PluralRule=1, Code="ur"}},
|
||||
{"Uzbek", new LanguageCodeDef {PluralRule=2, Code="uz"}},
|
||||
/**/{"Venda", new LanguageCodeDef {PluralRule=1, Code="ve", GoogleCode="-"}},
|
||||
{"Vietnamese", new LanguageCodeDef {PluralRule=1, Code="vi"}},
|
||||
/**/{"Volapük", new LanguageCodeDef {PluralRule=1, Code="vo", GoogleCode="-"}},
|
||||
/**/{"Walloon", new LanguageCodeDef {PluralRule=1, Code="wa", GoogleCode="-"}},
|
||||
{"Welsh", new LanguageCodeDef {PluralRule=16, Code="cy"}},
|
||||
/**/{"Wolof", new LanguageCodeDef {PluralRule=1, Code="wo", GoogleCode="-"}},
|
||||
/**/{"Frisian", new LanguageCodeDef {PluralRule=1, Code="fy"}},
|
||||
{"Xhosa", new LanguageCodeDef {PluralRule=1, Code="xh"}},
|
||||
{"Yiddish", new LanguageCodeDef {PluralRule=1, Code="yi"}},
|
||||
/**/{"Yoruba", new LanguageCodeDef {PluralRule=1, Code="yo"}},
|
||||
/**/{"Zhuang", new LanguageCodeDef {PluralRule=1, Code="za", GoogleCode="-"}},
|
||||
{"Zulu", new LanguageCodeDef {PluralRule=1, Code="zu"}}
|
||||
};
|
||||
|
||||
static int GetPluralRule( string langCode )
|
||||
{
|
||||
if (langCode.Length > 2)
|
||||
langCode = langCode.Substring(0, 2);
|
||||
langCode = langCode.ToLower();
|
||||
|
||||
foreach (var kvp in mLanguageDef)
|
||||
if (kvp.Value.Code == langCode)
|
||||
{
|
||||
return kvp.Value.PluralRule;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
|
||||
//http://cldr.unicode.org/cldr-features#TOC-Locale-specific-patterns-for-formatting-and-parsing:
|
||||
//http://cldr.unicode.org/index/cldr-spec/plural-rules
|
||||
public static bool LanguageHasPluralType( string langCode, string pluralType )
|
||||
{
|
||||
if (pluralType == "Plural" || pluralType=="Zero" || pluralType=="One")
|
||||
return true;
|
||||
|
||||
int rule = GetPluralRule (langCode);
|
||||
|
||||
switch (rule)
|
||||
{
|
||||
case 3: // Celtic (Scottish Gaelic)
|
||||
return pluralType=="Two" || pluralType=="Few";
|
||||
|
||||
case 4: // Families: Romanic (Romanian)
|
||||
case 5: // Families: Baltic (Latvian, Lithuanian)
|
||||
case 6: // Families: Slavic (Belarusian, Bosnian, Croatian, Serbian, Russian, Ukrainian)
|
||||
case 7: // Families: Slavic (Slovak, Czech)
|
||||
case 8: // Families: Slavic (Polish)
|
||||
return pluralType=="Few";
|
||||
|
||||
case 9: // Families: Slavic (Slovenian, Sorbian)
|
||||
return pluralType=="Two" || pluralType=="Few";
|
||||
|
||||
case 10: // Families: Celtic (Irish Gaelic)
|
||||
case 11: // Families: Semitic (Arabic)
|
||||
case 15: // Families: Celtic (Breton)
|
||||
case 16: // Families: (Welsh)
|
||||
return pluralType=="Two" || pluralType=="Few" || pluralType=="Many";
|
||||
|
||||
case 12: // Families: Semitic (Maltese)
|
||||
return pluralType=="Few" || pluralType=="Many";
|
||||
|
||||
case 13: // Families: Slavic (Macedonian)
|
||||
return pluralType=="Two";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals
|
||||
public static ePluralType GetPluralType( string langCode, int n )
|
||||
{
|
||||
if (n == 0) return ePluralType.Zero;
|
||||
if (n == 1) return ePluralType.One;
|
||||
|
||||
int rule = GetPluralRule (langCode);
|
||||
|
||||
switch (rule)
|
||||
{
|
||||
case 0: // Families: Asian (Chinese, Japanese, Korean), Persian, Turkic/Altaic (Turkish), Thai, Lao
|
||||
return ePluralType.Plural;
|
||||
|
||||
case 1: // Families: Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish), Finno-Ugric (Estonian, Finnish, Hungarian), Language isolate (Basque), Latin/Greek (Greek), Semitic (Hebrew), Romanic (Italian, Portuguese, Spanish, Catalan), Vietnamese
|
||||
return n==1 ? ePluralType.One : ePluralType.Plural;
|
||||
|
||||
case 2: // Families: Romanic (French, Brazilian Portuguese)
|
||||
return n<=1 ? ePluralType.One : ePluralType.Plural;
|
||||
|
||||
case 3: // Celtic (Scottish Gaelic)
|
||||
return n==1 || n==11 ? ePluralType.One :
|
||||
n==2 || n==12 ? ePluralType.Two :
|
||||
inRange(n,3,10) || inRange(n,13,19) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 4: // Families: Romanic (Romanian)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange(n%100, 1, 19) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 5: // Families: Baltic (Latvian, Lithuanian)
|
||||
return n%10==1 && n%100!=11 ? ePluralType.One :
|
||||
n%10>=2 && (n%100<10 || n%100>=20) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 6: // Families: Slavic (Belarusian, Bosnian, Croatian, Serbian, Russian, Ukrainian)
|
||||
return n % 10 == 1 && n % 100 != 11 ? ePluralType.One :
|
||||
inRange (n%10,2,4) && !inRange (n%100,12,14) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 7: // Families: Slavic (Slovak, Czech)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange(n,2,4) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 8: // Families: Slavic (Polish)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange (n%10,2,4) && !inRange (n%100,12,14) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 9: // Families: Slavic (Slovenian, Sorbian)
|
||||
return n%100==1 ? ePluralType.One :
|
||||
n%100==2 ? ePluralType.Two :
|
||||
inRange(n%100,3,4) ? ePluralType.Few : ePluralType.Plural;
|
||||
|
||||
case 10: // Families: Celtic (Irish Gaelic)
|
||||
return n==1 ? ePluralType.One :
|
||||
n==2 ? ePluralType.Two :
|
||||
inRange(n, 3,6) ? ePluralType.Few :
|
||||
inRange(n, 7,10)? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 11: // Families: Semitic (Arabic)
|
||||
return n==0 ? ePluralType.Zero :
|
||||
n==1 ? ePluralType.One :
|
||||
n==2 ? ePluralType.Two :
|
||||
inRange(n%100,3,10) ? ePluralType.Few :
|
||||
n%100>=11 ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 12: // Families: Semitic (Maltese)
|
||||
return n==1 ? ePluralType.One :
|
||||
inRange(n%100, 1, 10) ? ePluralType.Few :
|
||||
inRange(n%100, 11,19) ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 13: // Families: Slavic (Macedonian)
|
||||
return n % 10 == 1 ? ePluralType.One :
|
||||
n % 10 == 2 ? ePluralType.Two : ePluralType.Plural;
|
||||
|
||||
case 14: // Plural rule #15 (2 forms)
|
||||
return n%10==1 && n%100!=11 ? ePluralType.One : ePluralType.Plural;
|
||||
|
||||
case 15: // Families: Celtic (Breton)
|
||||
return n % 10 == 1 && n % 100 != 11 && n % 100 != 71 && n % 100 != 91 ? ePluralType.One :
|
||||
n % 10 == 2 && n % 100 != 12 && n % 100 != 72 && n % 100 != 92 ? ePluralType.Two :
|
||||
(n % 10 == 3 || n % 10 == 4 || n % 10 == 9) && n % 100 != 13 && n % 100 != 14 && n % 100 != 19 && n % 100 != 73 && n % 100 != 74 && n % 100 != 79 && n % 100 != 93 && n % 100 != 94 && n % 100 != 99 ? ePluralType.Few :
|
||||
n%1000000==0 ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
case 16: // Families: (Welsh)
|
||||
return n==0 ? ePluralType.Zero :
|
||||
n==1 ? ePluralType.One :
|
||||
n==2 ? ePluralType.Two :
|
||||
n==3 ? ePluralType.Few :
|
||||
n==6 ? ePluralType.Many : ePluralType.Plural;
|
||||
|
||||
}
|
||||
|
||||
return ePluralType.Plural;
|
||||
}
|
||||
|
||||
// A number that belong to the pluralType form
|
||||
public static int GetPluralTestNumber( string langCode, ePluralType pluralType )
|
||||
{
|
||||
switch (pluralType)
|
||||
{
|
||||
case ePluralType.Zero:
|
||||
return 0;
|
||||
|
||||
case ePluralType.One:
|
||||
return 1;
|
||||
|
||||
case ePluralType.Few:
|
||||
return 3;
|
||||
|
||||
case ePluralType.Many:
|
||||
{
|
||||
int rule = GetPluralRule (langCode);
|
||||
if (rule == 10) return 8;
|
||||
if (rule == 11 || rule==12) return 13;
|
||||
if (rule == 15) return 1000000;
|
||||
return 6;
|
||||
}
|
||||
|
||||
default:
|
||||
return 936;
|
||||
}
|
||||
}
|
||||
|
||||
static bool inRange(int amount, int min, int max)
|
||||
{
|
||||
return amount >= min && amount <= max;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26e29b3e77176de4cbb64a3ec85beee6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
86
Assets/I2/Localization/Scripts/Google/GoogleTranslation.cs
Normal file
86
Assets/I2/Localization/Scripts/Google/GoogleTranslation.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
public static partial class GoogleTranslation
|
||||
{
|
||||
public delegate void fnOnTranslated(string Translation, string Error);
|
||||
|
||||
public static bool CanTranslate ()
|
||||
{
|
||||
return LocalizationManager.Sources.Count > 0 &&
|
||||
!string.IsNullOrEmpty (LocalizationManager.GetWebServiceURL());
|
||||
}
|
||||
|
||||
|
||||
// LanguageCodeFrom can be "auto"
|
||||
// After the translation is returned from Google, it will call OnTranslationReady(TranslationResult, ErrorMsg)
|
||||
// TranslationResult will be null if translation failed
|
||||
public static void Translate( string text, string LanguageCodeFrom, string LanguageCodeTo, fnOnTranslated OnTranslationReady )
|
||||
{
|
||||
LocalizationManager.InitializeIfNeeded();
|
||||
if (!CanTranslate())
|
||||
{
|
||||
OnTranslationReady(null, "WebService is not set correctly or needs to be reinstalled");
|
||||
return;
|
||||
}
|
||||
//LanguageCodeTo = GoogleLanguages.GetGoogleLanguageCode(LanguageCodeTo);
|
||||
|
||||
if (LanguageCodeTo==LanguageCodeFrom)
|
||||
{
|
||||
OnTranslationReady(text, null);
|
||||
return;
|
||||
}
|
||||
|
||||
TranslationDictionary queries = new TranslationDictionary(System.StringComparer.Ordinal);
|
||||
|
||||
|
||||
// Unsupported language
|
||||
if (string.IsNullOrEmpty(LanguageCodeTo))
|
||||
{
|
||||
OnTranslationReady(string.Empty, null);
|
||||
return;
|
||||
}
|
||||
CreateQueries(text, LanguageCodeFrom, LanguageCodeTo, queries); // can split plurals and specializations into several queries
|
||||
|
||||
Translate(queries, (results,error)=>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(error) || results.Count==0)
|
||||
{
|
||||
OnTranslationReady(null, error);
|
||||
return;
|
||||
}
|
||||
|
||||
string result = RebuildTranslation( text, queries, LanguageCodeTo); // gets the result from google and rebuilds the text from multiple queries if its is plurals
|
||||
OnTranslationReady( result, null );
|
||||
});
|
||||
}
|
||||
|
||||
// Query google for the translation and waits until google returns
|
||||
// On some Unity versions (e.g. 2017.1f1) unity doesn't handle well waiting for WWW in the main thread, so this call can fail
|
||||
// In those cases, its advisable to use the Async version (GoogleTranslation.Translate(....))
|
||||
public static string ForceTranslate ( string text, string LanguageCodeFrom, string LanguageCodeTo )
|
||||
{
|
||||
TranslationDictionary dict = new TranslationDictionary(System.StringComparer.Ordinal);
|
||||
AddQuery(text, LanguageCodeFrom, LanguageCodeTo, dict);
|
||||
|
||||
var job = new TranslationJob_Main(dict, null);
|
||||
while (true)
|
||||
{
|
||||
var state = job.GetState();
|
||||
if (state == TranslationJob.eJobState.Running)
|
||||
continue;
|
||||
|
||||
if (state == TranslationJob.eJobState.Failed)
|
||||
return null;
|
||||
|
||||
//TranslationJob.eJobState.Succeeded
|
||||
return GetQueryResult( text, "", dict);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc4d0073f9e452047bd31b01de2bbd82
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
175
Assets/I2/Localization/Scripts/Google/GoogleTranslation_Post.cs
Normal file
175
Assets/I2/Localization/Scripts/Google/GoogleTranslation_Post.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
|
||||
public static partial class GoogleTranslation
|
||||
{
|
||||
static List<UnityWebRequest> mCurrentTranslations = new List<UnityWebRequest>();
|
||||
static List<TranslationJob> mTranslationJobs = new List<TranslationJob>();
|
||||
|
||||
public delegate void fnOnTranslationReady(TranslationDictionary dict, string error);
|
||||
|
||||
#region Multiple Translations
|
||||
|
||||
public static void Translate( TranslationDictionary requests, fnOnTranslationReady OnTranslationReady, bool usePOST = true )
|
||||
{
|
||||
//WWW www = GetTranslationWWW( requests, usePOST );
|
||||
//I2.Loc.CoroutineManager.Start(WaitForTranslation(www, OnTranslationReady, requests));
|
||||
AddTranslationJob( new TranslationJob_Main(requests, OnTranslationReady) );
|
||||
}
|
||||
|
||||
public static bool ForceTranslate(TranslationDictionary requests, bool usePOST = true)
|
||||
{
|
||||
var job = new TranslationJob_Main(requests, null);
|
||||
while (true)
|
||||
{
|
||||
var state = job.GetState();
|
||||
if (state == TranslationJob.eJobState.Running)
|
||||
continue;
|
||||
|
||||
if (state == TranslationJob.eJobState.Failed)
|
||||
return false;
|
||||
|
||||
//TranslationJob.eJobState.Succeeded
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<string> ConvertTranslationRequest(TranslationDictionary requests, bool encodeGET)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (var kvp in requests)
|
||||
{
|
||||
var request = kvp.Value;
|
||||
if (sb.Length > 0)
|
||||
sb.Append("<I2Loc>");
|
||||
|
||||
sb.Append(GoogleLanguages.GetGoogleLanguageCode(request.LanguageCode));
|
||||
sb.Append(":");
|
||||
for (int i = 0; i < request.TargetLanguagesCode.Length; ++i)
|
||||
{
|
||||
if (i != 0) sb.Append(",");
|
||||
sb.Append(GoogleLanguages.GetGoogleLanguageCode(request.TargetLanguagesCode[i]));
|
||||
}
|
||||
sb.Append("=");
|
||||
|
||||
var text = TitleCase(request.Text) == request.Text ? request.Text.ToLowerInvariant() : request.Text;
|
||||
|
||||
if (!encodeGET)
|
||||
{
|
||||
sb.Append(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(Uri.EscapeDataString(text));
|
||||
if (sb.Length > 4000)
|
||||
{
|
||||
results.Add(sb.ToString());
|
||||
sb.Length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
results.Add(sb.ToString());
|
||||
return results;
|
||||
}
|
||||
|
||||
static void AddTranslationJob( TranslationJob job )
|
||||
{
|
||||
mTranslationJobs.Add(job);
|
||||
if (mTranslationJobs.Count==1)
|
||||
{
|
||||
CoroutineManager.Start(WaitForTranslations());
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerator WaitForTranslations()
|
||||
{
|
||||
while (mTranslationJobs.Count > 0)
|
||||
{
|
||||
var jobs = mTranslationJobs.ToArray();
|
||||
foreach (var job in jobs)
|
||||
{
|
||||
if (job.GetState() != TranslationJob.eJobState.Running)
|
||||
mTranslationJobs.Remove(job);
|
||||
}
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static string ParseTranslationResult( string html, TranslationDictionary requests )
|
||||
{
|
||||
//Debug.Log(html);
|
||||
// Handle google restricting the webservice to run
|
||||
if (html.StartsWith("<!DOCTYPE html>") || html.StartsWith("<HTML>"))
|
||||
{
|
||||
if (html.Contains("The script completed but did not return anything"))
|
||||
return "The current Google WebService is not supported.\nPlease, delete the WebService from the Google Drive and Install the latest version.";
|
||||
if (html.Contains("Service invoked too many times in a short time"))
|
||||
return ""; // ignore and try again
|
||||
return "There was a problem contacting the WebService. Please try again later\n" + html;
|
||||
}
|
||||
|
||||
string[] texts = html.Split (new[]{"<I2Loc>"}, StringSplitOptions.None);
|
||||
string[] splitter = {"<i2>"};
|
||||
int i = 0;
|
||||
|
||||
var Keys = requests.Keys.ToArray();
|
||||
foreach (var text in Keys)
|
||||
{
|
||||
var temp = FindQueryFromOrigText(text, requests);
|
||||
var fullText = texts[i++];
|
||||
if (temp.Tags != null)
|
||||
{
|
||||
//for (int j = 0, jmax = temp.Tags.Length; j < jmax; ++j)
|
||||
for (int j = temp.Tags.Length-1; j>=0; --j)
|
||||
{
|
||||
fullText = fullText.Replace(GetGoogleNoTranslateTag(j), temp.Tags[j]);
|
||||
//fullText = fullText.Replace( /*"{[" + j + "]}"*/ ((char)(0x2600+j)).ToString(), temp.Tags[j]);
|
||||
}
|
||||
}
|
||||
|
||||
temp.Results = fullText.Split (splitter, StringSplitOptions.None);
|
||||
|
||||
// Google has problem translating this "This Is An Example" but not this "this is an example"
|
||||
if (TitleCase(text)==text)
|
||||
{
|
||||
for (int j=0; j<temp.Results.Length; ++j)
|
||||
temp.Results[j] = TitleCase(temp.Results[j]);
|
||||
}
|
||||
requests[temp.OrigText] = temp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsTranslating()
|
||||
{
|
||||
return mCurrentTranslations.Count>0 || mTranslationJobs.Count > 0;
|
||||
}
|
||||
|
||||
public static void CancelCurrentGoogleTranslations()
|
||||
{
|
||||
mCurrentTranslations.Clear ();
|
||||
foreach (var job in mTranslationJobs)
|
||||
{
|
||||
job.Dispose();
|
||||
}
|
||||
mTranslationJobs.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94b94d27ab6931c4abee1e4d3655b660
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,375 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
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[] { LanguageCodeTo } };
|
||||
query.Text = text;
|
||||
ParseNonTranslatableElements(ref query);
|
||||
dict[text] = query;
|
||||
}
|
||||
else
|
||||
{
|
||||
var query = dict[text];
|
||||
if (Array.IndexOf(query.TargetLanguagesCode, LanguageCodeTo) < 0)
|
||||
{
|
||||
query.TargetLanguagesCode = query.TargetLanguagesCode.Concat(new[] { 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 = 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("{[", StringComparison.Ordinal);
|
||||
if (idx < 0) return false;
|
||||
return text.IndexOf("]}", idx, StringComparison.Ordinal) > 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("{[#", StringComparison.Ordinal);
|
||||
if (idx0 < 0)
|
||||
{
|
||||
if (forceTag) return null;
|
||||
idx0 = text.IndexOf("{[", StringComparison.Ordinal); // fallback to the first paremeter if no one has the # tag
|
||||
}
|
||||
if (idx0 < 0)
|
||||
return null;
|
||||
|
||||
int idx1 = text.IndexOf("]}", idx0+2, StringComparison.Ordinal);
|
||||
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, StringComparison.Ordinal);
|
||||
if (idx0>=0)
|
||||
{
|
||||
idx0 += pluralType.Length;
|
||||
int idx1 = text.IndexOf("[i2p_",idx0, StringComparison.Ordinal);
|
||||
if (idx1 < 0) idx1 = text.Length;
|
||||
|
||||
return text.Substring(idx0, idx1 - idx0);
|
||||
}
|
||||
|
||||
// PluralType not found, fallback to the first one
|
||||
idx0 = text.IndexOf("[i2p_", StringComparison.Ordinal);
|
||||
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("]", StringComparison.Ordinal);
|
||||
if (idx0 < 0) return text; // starts like a plural, but has none
|
||||
|
||||
idx0 += 1;
|
||||
int idx2 = text.IndexOf("[i2p_", idx0, StringComparison.Ordinal);
|
||||
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), StringComparison.Ordinal))
|
||||
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("{[", StringComparison.Ordinal) && fulltag.EndsWith("]}", StringComparison.Ordinal))
|
||||
{
|
||||
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 = 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>(StringComparer.Ordinal);
|
||||
|
||||
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 StringBuilder();
|
||||
|
||||
string pluralTranslation = null;
|
||||
bool forcePluralParam = hasPluralParams;
|
||||
|
||||
|
||||
for (var i = ePluralType.Plural; i >= 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 CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 206e4bf72a490864e9bcb59edbdddaed
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1109
Assets/I2/Localization/Scripts/Google/SimpleJSON.cs
Normal file
1109
Assets/I2/Localization/Scripts/Google/SimpleJSON.cs
Normal file
File diff suppressed because it is too large
Load Diff
10
Assets/I2/Localization/Scripts/Google/SimpleJSON.cs.meta
Normal file
10
Assets/I2/Localization/Scripts/Google/SimpleJSON.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6bd173cd8524b04daa3dabce666b456
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Assets/I2/Localization/Scripts/Google/TranslationJob.cs
Normal file
34
Assets/I2/Localization/Scripts/Google/TranslationJob.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
|
||||
public class TranslationJob : IDisposable
|
||||
{
|
||||
public eJobState mJobState = eJobState.Running;
|
||||
|
||||
public enum eJobState { Running, Succeeded, Failed }
|
||||
|
||||
public virtual eJobState GetState() { return mJobState; }
|
||||
|
||||
public virtual void Dispose() { }
|
||||
|
||||
}
|
||||
|
||||
public class TranslationJob_WWW : TranslationJob
|
||||
{
|
||||
public UnityWebRequest www;
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (www!=null)
|
||||
www.Dispose();
|
||||
www = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
10
Assets/I2/Localization/Scripts/Google/TranslationJob.cs.meta
Normal file
10
Assets/I2/Localization/Scripts/Google/TranslationJob.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dae211a5bb44db46a568fb70fca3296
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
79
Assets/I2/Localization/Scripts/Google/TranslationJob_GET.cs
Normal file
79
Assets/I2/Localization/Scripts/Google/TranslationJob_GET.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
public class TranslationJob_GET : TranslationJob_WWW
|
||||
{
|
||||
TranslationDictionary _requests;
|
||||
GoogleTranslation.fnOnTranslationReady _OnTranslationReady;
|
||||
List<string> mQueries;
|
||||
public string mErrorMessage;
|
||||
|
||||
public TranslationJob_GET(TranslationDictionary requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady)
|
||||
{
|
||||
_requests = requests;
|
||||
_OnTranslationReady = OnTranslationReady;
|
||||
|
||||
mQueries = GoogleTranslation.ConvertTranslationRequest(requests, true);
|
||||
|
||||
GetState();
|
||||
}
|
||||
|
||||
void ExecuteNextQuery()
|
||||
{
|
||||
if (mQueries.Count == 0)
|
||||
{
|
||||
mJobState = eJobState.Succeeded;
|
||||
return;
|
||||
}
|
||||
|
||||
int lastQuery = mQueries.Count - 1;
|
||||
var query = mQueries[lastQuery];
|
||||
mQueries.RemoveAt(lastQuery);
|
||||
|
||||
string url = $"{LocalizationManager.GetWebServiceURL()}?action=Translate&list={query}";
|
||||
www = UnityWebRequest.Get(url);
|
||||
I2Utils.SendWebRequest(www);
|
||||
}
|
||||
|
||||
public override eJobState GetState()
|
||||
{
|
||||
if (www != null && www.isDone)
|
||||
{
|
||||
ProcessResult(www.downloadHandler.data, www.error);
|
||||
www.Dispose();
|
||||
www = null;
|
||||
}
|
||||
|
||||
if (www==null)
|
||||
{
|
||||
ExecuteNextQuery();
|
||||
}
|
||||
|
||||
return mJobState;
|
||||
}
|
||||
|
||||
public void ProcessResult(byte[] bytes, string errorMsg)
|
||||
{
|
||||
if (string.IsNullOrEmpty(errorMsg))
|
||||
{
|
||||
var wwwText = Encoding.UTF8.GetString(bytes, 0, bytes.Length); //www.text
|
||||
errorMsg = GoogleTranslation.ParseTranslationResult(wwwText, _requests);
|
||||
|
||||
if (string.IsNullOrEmpty(errorMsg))
|
||||
{
|
||||
if (_OnTranslationReady!=null)
|
||||
_OnTranslationReady(_requests, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mJobState = eJobState.Failed;
|
||||
mErrorMessage = errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13df42f7287eccc4399bc757d577030e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
102
Assets/I2/Localization/Scripts/Google/TranslationJob_Main.cs
Normal file
102
Assets/I2/Localization/Scripts/Google/TranslationJob_Main.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
public class TranslationJob_Main : TranslationJob
|
||||
{
|
||||
TranslationJob_WEB mWeb;
|
||||
TranslationJob_POST mPost;
|
||||
TranslationJob_GET mGet;
|
||||
|
||||
TranslationDictionary _requests;
|
||||
GoogleTranslation.fnOnTranslationReady _OnTranslationReady;
|
||||
public string mErrorMessage;
|
||||
|
||||
public TranslationJob_Main(TranslationDictionary requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady)
|
||||
{
|
||||
_requests = requests;
|
||||
_OnTranslationReady = OnTranslationReady;
|
||||
|
||||
//mWeb = new TranslationJob_WEB(requests, OnTranslationReady);
|
||||
mPost = new TranslationJob_POST(requests, OnTranslationReady);
|
||||
}
|
||||
|
||||
public override eJobState GetState()
|
||||
{
|
||||
if (mWeb != null)
|
||||
{
|
||||
var state = mWeb.GetState();
|
||||
switch (state)
|
||||
{
|
||||
case eJobState.Running: return eJobState.Running;
|
||||
case eJobState.Succeeded:
|
||||
{
|
||||
mJobState = eJobState.Succeeded;
|
||||
break;
|
||||
}
|
||||
case eJobState.Failed:
|
||||
{
|
||||
mWeb.Dispose();
|
||||
mWeb = null;
|
||||
mPost = new TranslationJob_POST(_requests, _OnTranslationReady);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mPost != null)
|
||||
{
|
||||
var state = mPost.GetState();
|
||||
switch (state)
|
||||
{
|
||||
case eJobState.Running: return eJobState.Running;
|
||||
case eJobState.Succeeded:
|
||||
{
|
||||
mJobState = eJobState.Succeeded;
|
||||
break;
|
||||
}
|
||||
case eJobState.Failed:
|
||||
{
|
||||
mPost.Dispose();
|
||||
mPost = null;
|
||||
mGet = new TranslationJob_GET(_requests, _OnTranslationReady);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mGet != null)
|
||||
{
|
||||
var state = mGet.GetState();
|
||||
switch (state)
|
||||
{
|
||||
case eJobState.Running: return eJobState.Running;
|
||||
case eJobState.Succeeded:
|
||||
{
|
||||
mJobState = eJobState.Succeeded;
|
||||
break;
|
||||
}
|
||||
case eJobState.Failed:
|
||||
{
|
||||
mErrorMessage = mGet.mErrorMessage;
|
||||
if (_OnTranslationReady != null)
|
||||
_OnTranslationReady(_requests, mErrorMessage);
|
||||
mGet.Dispose();
|
||||
mGet = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mJobState;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (mPost != null) mPost.Dispose();
|
||||
if (mGet != null) mGet.Dispose();
|
||||
mPost = null;
|
||||
mGet = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6aed7ae05f9c254596b3728c5811bdb
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
60
Assets/I2/Localization/Scripts/Google/TranslationJob_POST.cs
Normal file
60
Assets/I2/Localization/Scripts/Google/TranslationJob_POST.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
public class TranslationJob_POST : TranslationJob_WWW
|
||||
{
|
||||
TranslationDictionary _requests;
|
||||
GoogleTranslation.fnOnTranslationReady _OnTranslationReady;
|
||||
|
||||
public TranslationJob_POST(TranslationDictionary requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady)
|
||||
{
|
||||
_requests = requests;
|
||||
_OnTranslationReady = OnTranslationReady;
|
||||
|
||||
var data = GoogleTranslation.ConvertTranslationRequest(requests, false);
|
||||
|
||||
WWWForm form = new WWWForm();
|
||||
form.AddField("action", "Translate");
|
||||
form.AddField("list", data[0]);
|
||||
|
||||
www = UnityWebRequest.Post(LocalizationManager.GetWebServiceURL(), form);
|
||||
I2Utils.SendWebRequest(www);
|
||||
}
|
||||
|
||||
public override eJobState GetState()
|
||||
{
|
||||
if (www != null && www.isDone)
|
||||
{
|
||||
ProcessResult(www.downloadHandler.data, www.error);
|
||||
www.Dispose();
|
||||
www = null;
|
||||
}
|
||||
|
||||
return mJobState;
|
||||
}
|
||||
|
||||
public void ProcessResult(byte[] bytes, string errorMsg)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(errorMsg))
|
||||
{
|
||||
// check for
|
||||
//if (errorMsg.Contains("rewind")) // "necessary data rewind wasn't possible"
|
||||
mJobState = eJobState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
var wwwText = Encoding.UTF8.GetString(bytes, 0, bytes.Length); //www.text
|
||||
errorMsg = GoogleTranslation.ParseTranslationResult(wwwText, _requests);
|
||||
if (_OnTranslationReady!=null)
|
||||
_OnTranslationReady(_requests, errorMsg);
|
||||
mJobState = eJobState.Succeeded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3450e33294f339348ae4e52731974230
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
169
Assets/I2/Localization/Scripts/Google/TranslationJob_WEB.cs
Normal file
169
Assets/I2/Localization/Scripts/Google/TranslationJob_WEB.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace I2.Loc
|
||||
{
|
||||
using TranslationDictionary = Dictionary<string, TranslationQuery>;
|
||||
|
||||
public class TranslationJob_WEB : TranslationJob_WWW
|
||||
{
|
||||
TranslationDictionary _requests;
|
||||
GoogleTranslation.fnOnTranslationReady _OnTranslationReady;
|
||||
public string mErrorMessage;
|
||||
|
||||
string mCurrentBatch_ToLanguageCode;
|
||||
string mCurrentBatch_FromLanguageCode;
|
||||
List<string> mCurrentBatch_Text;
|
||||
|
||||
List<KeyValuePair<string, string>> mQueries;
|
||||
|
||||
public TranslationJob_WEB(TranslationDictionary requests, GoogleTranslation.fnOnTranslationReady OnTranslationReady)
|
||||
{
|
||||
_requests = requests;
|
||||
_OnTranslationReady = OnTranslationReady;
|
||||
|
||||
FindAllQueries();
|
||||
ExecuteNextBatch();
|
||||
}
|
||||
|
||||
void FindAllQueries()
|
||||
{
|
||||
mQueries = new List<KeyValuePair<string, string>>();
|
||||
foreach (var kvp in _requests)
|
||||
{
|
||||
foreach (var langCode in kvp.Value.TargetLanguagesCode)
|
||||
{
|
||||
mQueries.Add(new KeyValuePair<string, string>(kvp.Value.OrigText, kvp.Value.LanguageCode+":"+langCode));
|
||||
}
|
||||
}
|
||||
|
||||
mQueries.Sort((a, b) => a.Value.CompareTo(b.Value));
|
||||
}
|
||||
|
||||
void ExecuteNextBatch()
|
||||
{
|
||||
if (mQueries.Count==0)
|
||||
{
|
||||
mJobState = eJobState.Succeeded;
|
||||
return;
|
||||
}
|
||||
mCurrentBatch_Text = new List<string>();
|
||||
|
||||
string lastLangCode = null;
|
||||
int maxLength = 200;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
int i;
|
||||
for (i=0; i<mQueries.Count; ++i)
|
||||
{
|
||||
var text = mQueries[i].Key;
|
||||
var langCode = mQueries[i].Value;
|
||||
|
||||
if (lastLangCode==null || langCode==lastLangCode)
|
||||
{
|
||||
if (i != 0)
|
||||
sb.Append("|||");
|
||||
sb.Append(text);
|
||||
|
||||
mCurrentBatch_Text.Add(text);
|
||||
lastLangCode = langCode;
|
||||
}
|
||||
if (sb.Length > maxLength)
|
||||
break;
|
||||
}
|
||||
mQueries.RemoveRange(0, i);
|
||||
|
||||
var fromtoLang = lastLangCode.Split(':');
|
||||
mCurrentBatch_FromLanguageCode = fromtoLang[0];
|
||||
mCurrentBatch_ToLanguageCode = fromtoLang[1];
|
||||
|
||||
string url = string.Format ("http://www.google.com/translate_t?hl=en&vi=c&ie=UTF8&oe=UTF8&submit=Translate&langpair={0}|{1}&text={2}", mCurrentBatch_FromLanguageCode, mCurrentBatch_ToLanguageCode, Uri.EscapeUriString( sb.ToString() ));
|
||||
Debug.Log(url);
|
||||
|
||||
www = UnityWebRequest.Get(url);
|
||||
I2Utils.SendWebRequest(www);
|
||||
}
|
||||
|
||||
public override eJobState GetState()
|
||||
{
|
||||
if (www != null && www.isDone)
|
||||
{
|
||||
ProcessResult(www.downloadHandler.data, www.error);
|
||||
www.Dispose();
|
||||
www = null;
|
||||
}
|
||||
|
||||
if (www == null)
|
||||
{
|
||||
ExecuteNextBatch();
|
||||
}
|
||||
|
||||
return mJobState;
|
||||
}
|
||||
|
||||
public void ProcessResult(byte[] bytes, string errorMsg)
|
||||
{
|
||||
if (string.IsNullOrEmpty(errorMsg))
|
||||
{
|
||||
var wwwText = Encoding.UTF8.GetString(bytes, 0, bytes.Length); //www.text
|
||||
var result = ParseTranslationResult(wwwText, "aab");
|
||||
//errorMsg = GoogleTranslation.ParseTranslationResult(wwwText, _requests);
|
||||
Debug.Log(result);
|
||||
|
||||
if (string.IsNullOrEmpty(errorMsg))
|
||||
{
|
||||
if (_OnTranslationReady != null)
|
||||
_OnTranslationReady(_requests, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mJobState = eJobState.Failed;
|
||||
mErrorMessage = errorMsg;
|
||||
}
|
||||
|
||||
string ParseTranslationResult( string html, string OriginalText )
|
||||
{
|
||||
try
|
||||
{
|
||||
// This is a Hack for reading Google Translation while Google doens't change their response format
|
||||
int iStart = html.IndexOf("TRANSLATED_TEXT='", StringComparison.Ordinal) + "TRANSLATED_TEXT='".Length;
|
||||
int iEnd = html.IndexOf("';var", iStart, StringComparison.Ordinal);
|
||||
|
||||
string Translation = html.Substring( iStart, iEnd-iStart);
|
||||
|
||||
// Convert to normalized HTML
|
||||
Translation = Regex.Replace(Translation, @"\\x([a-fA-F0-9]{2})",
|
||||
match => char.ConvertFromUtf32(int.Parse(match.Groups[1].Value, NumberStyles.HexNumber)));
|
||||
|
||||
// Convert ASCII Characters
|
||||
Translation = Regex.Replace(Translation, @"&#(\d+);",
|
||||
match => char.ConvertFromUtf32(int.Parse(match.Groups[1].Value)));
|
||||
|
||||
Translation = Translation.Replace("<br>", "\n");
|
||||
|
||||
if (OriginalText.ToUpper()==OriginalText)
|
||||
Translation = Translation.ToUpper();
|
||||
else
|
||||
if (GoogleTranslation.UppercaseFirst(OriginalText)==OriginalText)
|
||||
Translation = GoogleTranslation.UppercaseFirst(Translation);
|
||||
else
|
||||
if (GoogleTranslation.TitleCase(OriginalText)==OriginalText)
|
||||
Translation = GoogleTranslation.TitleCase(Translation);
|
||||
|
||||
return Translation;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError(ex.Message);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b72399bd2ff39042b1320bb943e0a20
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user