From 85553832ead1a96f88726cd2b35cb6ff1d8b8cc8 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Sat, 24 Aug 2019 15:24:57 -0400 Subject: Attempt number 2 on localization --- .../Lean/Localization/Scripts/LeanLanguageCSV.cs | 303 +++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 Assets/Packages/Lean/Localization/Scripts/LeanLanguageCSV.cs (limited to 'Assets/Packages/Lean/Localization/Scripts/LeanLanguageCSV.cs') diff --git a/Assets/Packages/Lean/Localization/Scripts/LeanLanguageCSV.cs b/Assets/Packages/Lean/Localization/Scripts/LeanLanguageCSV.cs new file mode 100644 index 0000000..f8a89b2 --- /dev/null +++ b/Assets/Packages/Lean/Localization/Scripts/LeanLanguageCSV.cs @@ -0,0 +1,303 @@ +using UnityEngine; +using System.Collections.Generic; +using Lean.Common; +#if UNITY_EDITOR +using UnityEditor; + +namespace Lean.Localization.Examples +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(LeanLanguageCSV), true)] + public class LeanLanguageCSV_Inspector : LeanInspector + { + protected override void DrawInspector() + { + Draw("Source", "The text asset that contains all the translations."); + Draw("Language", "The language of the translations in the source file."); + Draw("Separator", "The string separating the phrase name from the translation."); + Draw("NewLine", "The string denoting a new line within a translation."); + Draw("Comment", "The (optional) string separating the translation from the comment (empty = no comments)."); + + EditorGUILayout.Separator(); + + EditorGUI.BeginDisabledGroup(true); + EditorGUILayout.LabelField("CollectItem" + Target.Separator + "アイテム" + Target.NewLine + "集めました" + Target.Comment + "Comment here"); + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.Separator(); + + EditorGUILayout.BeginHorizontal(); + if (Any(t => t.Entries.Count > 0)) + { + if (GUILayout.Button("Clear") == true) + { + Each(t => t.Clear()); + } + } + if (GUILayout.Button("Load Now") == true) + { + Each(t => t.LoadFromSource()); + } + if (GUILayout.Button("Export") == true) + { + Each(t => t.ExportTextAsset()); + } + EditorGUILayout.EndHorizontal(); + + if (Targets.Length == 1) + { + var entries = Target.Entries; + + if (entries.Count > 0) + { + EditorGUILayout.Separator(); + + EditorGUI.BeginDisabledGroup(true); + foreach (var entry in entries) + { + EditorGUILayout.TextField(entry.Name, entry.Text); + } + EditorGUI.EndDisabledGroup(); + } + } + } + } +} +#endif + +namespace Lean.Localization +{ + /// This component will load localizations from a CSV file. By default they should be in the format: + /// Phrase Name Here = Translation Here // Optional Comment Here + [ExecuteInEditMode] + [HelpURL(LeanLocalization.HelpUrlPrefix + "LeanLanguageCSV")] + [AddComponentMenu(LeanLocalization.ComponentPathPrefix + "Language CSV")] + public class LeanLanguageCSV : LeanSource + { + [System.Serializable] + public class Entry + { + public string Name; + public string Text; + } + + /// The text asset that contains all the translations. + public TextAsset Source; + + /// The language of the translations in the source file. + [LeanLanguageName] + public string Language; + + /// The string separating the phrase name from the translation. + public string Separator = " = "; + + /// The string denoting a new line within a translation. + public string NewLine = "\\n"; + + /// The (optional) string separating the translation from the comment (empty = no comments). + public string Comment = " // "; + + /// This stores all currently loaded translations from this CSV file. + public List Entries { get { if (entries == null) entries = new List(); return entries; } } [SerializeField] private List entries; + + /// The characters used to separate each translation. + private static readonly char[] newlineCharacters = new char[] { '\r', '\n' }; + + private static Stack entryPool = new Stack(); + + public override void Compile(string primaryLanguage, string secondaryLanguage) + { + if (entries == null || entries.Count == 0) + { + if (Application.isPlaying == true) + { + LoadFromSource(); + } + } + + if (entries != null) + { + for (var i = entries.Count - 1; i >= 0; i--) + { + var entry = entries[i]; + var translation = LeanLocalization.RegisterTranslation(entry.Name); + + translation.Register(Language, this); + + if (Language == primaryLanguage) + { + translation.Data = entry.Text; + translation.Primary = true; + } + else if (Language == secondaryLanguage && translation.Primary == false) + { + translation.Data = entry.Text; + } + } + } + } + + [ContextMenu("Clear")] + public void Clear() + { + if (entries != null) + { + entries.Clear(); + + // Update translations? + if (LeanLocalization.CurrentLanguage == Language) + { + LeanLocalization.UpdateTranslations(); + } + } + } + + [ContextMenu("Load From Source")] + public void LoadFromSource() + { + if (Source != null && string.IsNullOrEmpty(Language) == false) + { + for (var i = Entries.Count - 1; i >= 0; i--) // NOTE: Property + { + entryPool.Push(entries[i]); + } + + entries.Clear(); + + // Split file into lines, and loop through them all + var lines = Source.text.Split(newlineCharacters, System.StringSplitOptions.RemoveEmptyEntries); + + for (var i = 0; i < lines.Length; i++) + { + var line = lines[i]; + var equalsIndex = line.IndexOf(Separator); + + // Only consider lines with the Separator character + if (equalsIndex != -1) + { + var name = line.Substring(0, equalsIndex).Trim(); + var text = line.Substring(equalsIndex + Separator.Length).Trim(); + + // Does this entry have a comment? + if (string.IsNullOrEmpty(Comment) == false) + { + var commentIndex = text.LastIndexOf(Comment); + + if (commentIndex != -1) + { + text = text.Substring(0, commentIndex).Trim(); + } + } + + // Replace newline markers with actual newlines + if (string.IsNullOrEmpty(NewLine) == false) + { + text = text.Replace(NewLine, System.Environment.NewLine); + } + + var entry = entryPool.Count > 0 ? entryPool.Pop() : new Entry(); + + entry.Name = name; + entry.Text = text; + + entries.Add(entry); + } + } + + // Update translations? + if (LeanLocalization.CurrentLanguage == Language) + { + LeanLocalization.UpdateTranslations(); + } + } + } + +#if UNITY_EDITOR + [ContextMenu("Export Text Asset")] + public void ExportTextAsset() + { + if (string.IsNullOrEmpty(Language) == false) + { + // Find where we want to save the file + var path = EditorUtility.SaveFilePanelInProject("Export Text Asset for " + Language, Language, "txt", ""); + + // Make sure we didn't cancel the panel + if (string.IsNullOrEmpty(path) == false) + { + if (LeanLocalization.CurrentLanguage == Language) + { + DoExportTextAsset(path); + } + else + { + var oldLanguage = LeanLocalization.CurrentLanguage; + + LeanLocalization.CurrentLanguage = Language; + + DoExportTextAsset(path); + + LeanLocalization.CurrentLanguage = oldLanguage; + } + } + } + } + + private void DoExportTextAsset(string path) + { + var data = ""; + var gaps = false; + + // Add all phrase names and existing translations to lines + foreach (var pair in LeanLocalization.CurrentTranslations) + { + var translation = pair.Value; + + if (gaps == true) + { + data += System.Environment.NewLine; + } + + data += pair.Key + Separator; + gaps = true; + + if (translation.Data is string) + { + var text = (string)translation.Data; + + // Replace all new line permutations with the new line token + text = text.Replace("\r\n", NewLine); + text = text.Replace("\n\r", NewLine); + text = text.Replace("\n", NewLine); + text = text.Replace("\r", NewLine); + + data += text; + } + } + + // Write text to file + using (var file = System.IO.File.OpenWrite(path)) + { + var encoding = new System.Text.UTF8Encoding(); + var bytes = encoding.GetBytes(data); + + file.Write(bytes, 0, bytes.Length); + } + + // Import asset into project + AssetDatabase.ImportAsset(path); + + // Replace Soure with new Text Asset? + var textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)); + + if (textAsset != null) + { + Source = textAsset; + + EditorGUIUtility.PingObject(textAsset); + + EditorUtility.SetDirty(this); + } + } +#endif + } +} \ No newline at end of file -- cgit v1.2.3