/// <summary> /// Load tokens for specified section. /// </summary> /// <param name="section">Section ID.</param> /// <param name="showWarning">If set to <c>true</c> show warning about already loaded section.</param> public static void LoadSection(R.sections.SectionID section, bool showWarning) { if (tokens[(int)section + 1] == null) { tokens[(int)section + 1] = new SectionTokens(); string xmlFile = R.sections.xmlFiles[(int)section]; Dictionary <string, int>[] tokenIds = R.tokenIds[(int)section + 1]; int stringCount = tokenIds[0].Count; int stringArrayCount = tokenIds[1].Count; int pluralsCount = tokenIds[2].Count; tokens[(int)section + 1].defaultLanguage = ParseXmlTokens(xmlFile, "", tokenIds, stringCount, stringArrayCount, pluralsCount); if (sLanguage != Language.Default) { string locale = AvailableLanguages.list[sLanguage]; tokens[(int)section + 1].selectedLanguage = ParseXmlTokens(xmlFile, locale, tokenIds, stringCount, stringArrayCount, pluralsCount); tokens[(int)section + 1].Optimize(); } sLoadedSections[section] = tokens[(int)section + 1]; } else { if (showWarning) { Debug.LogWarning("Section \"" + section + "\" already loaded"); } } }
static Translator() { #if UNITY_EDITOR CodeGenerator.Generate(); #endif sLanguageChangedAction = new UnityEvent(); sLoadedSections = new Dictionary <R.sections.SectionID, SectionTokens>(); #region Initialize default tokens tokens = new SectionTokens[(int)R.sections.SectionID.Count + 1]; tokens[0] = new SectionTokens(); string xmlFile = "strings.xml"; Dictionary <string, int>[] tokenIds = R.tokenIds[0]; int stringCount = tokenIds[0].Count; int stringArrayCount = tokenIds[1].Count; int pluralsCount = tokenIds[2].Count; tokens[0].defaultLanguage = ParseXmlTokens(xmlFile, "", tokenIds, stringCount, stringArrayCount, pluralsCount); #endregion #region Set language according to system language Language selectLanguage = LanguageSystemName.SystemLanguageToLanguage(Application.systemLanguage); if (AvailableLanguages.list.ContainsKey(selectLanguage)) { language = selectLanguage; } #endregion }
static Translator() { #if UNITY_EDITOR CodeGenerator.generate(); #endif mLanguageChangedAction = new UnityEvent(); mLoadedSections = new Dictionary<R.sections.SectionID, SectionTokens>(); #region Initialize default tokens tokens = new SectionTokens[(int)R.sections.SectionID.Count + 1]; tokens[0] = new SectionTokens(); string xmlFile = "strings.xml"; Dictionary<string, int>[] tokenIds = R.tokenIds[0]; int stringCount = tokenIds[0].Count; int stringArrayCount = tokenIds[1].Count; int pluralsCount = tokenIds[2].Count; tokens[0].defaultLanguage = parseXmlTokens(xmlFile, "", tokenIds, stringCount, stringArrayCount, pluralsCount); #endregion #region Set language according to system language Language selectLanguage = LanguageSystemName.systemLanguageToLanguage(Application.systemLanguage); if (AvailableLanguages.list.ContainsKey(selectLanguage)) { language = selectLanguage; } #endregion }
/// <summary> /// Generates source code for section tokens in R.cs file. /// </summary> /// <returns>Source code for section tokens.</returns> /// <param name="section">SectionTokens instance.</param> /// <param name="filename">Name of file.</param> /// <param name="indent">Indentation string.</param> private static string generateCodeForSectionTokens(SectionTokens section, string filename, string indent) { string res = indent + "/// <summary>\n" + indent + "/// Enumeration of all string tags in \"Assets/Resources/res/values/" + filename + "\"\n" + indent + "/// </summary>\n" + indent + "public enum strings\n" + indent + "{\n"; for (int i = 0; i < section.stringNames.Count; ++i) { string[] separators = new string[] { "\n", "\\n" }; string[] commentLines = section.stringComments[i] == null ? null : section.stringComments[i].Split(separators, StringSplitOptions.None); string[] valueLines = section.stringValues[i].Split(separators, StringSplitOptions.None); res += indent + " /// <summary>\n"; if (commentLines != null) { for (int j = 0; j < commentLines.Length; ++j) { res += indent + " /// <para>" + SecurityElement.Escape(commentLines[j]) + "</para>\n"; } } res += indent + " /// <para>Value:</para>\n"; if (valueLines != null) { for (int j = 0; j < valueLines.Length; ++j) { res += indent + " /// <para>" + SecurityElement.Escape(valueLines[j]) + "</para>\n"; } } res += indent + " /// </summary>\n" + indent + " " + section.stringNames[i] + "\n" + indent + " ,\n"; } res += indent + " /// <summary>\n" + indent + " /// Total amount of strings.\n" + indent + " /// </summary>\n" + indent + " Count // Should be last\n" + indent + "}\n" + "\n" + indent + "/// <summary>\n" + indent + "/// Enumeration of all string-array tags in \"Assets/Resources/res/values/" + filename + "\"\n" + indent + "/// </summary>\n" + indent + "public enum array\n" + indent + "{\n"; for (int i = 0; i < section.stringArrayNames.Count; ++i) { string[] separators = new string[] { "\n", "\\n" }; string[] commentLines = section.stringArrayComments[i] == null ? null : section.stringArrayComments[i].Split(separators, StringSplitOptions.None); res += indent + " /// <summary>\n"; if (commentLines != null) { for (int j = 0; j < commentLines.Length; ++j) { res += indent + " /// <para>" + commentLines[j] + "</para>\n"; } } res += indent + " /// <para>Value:</para>\n"; for (int j = 0; j < section.stringArrayValues[i].Count; ++j) { string[] valueCommentLines = section.stringArrayValuesComments[i][j] == null ? null : section.stringArrayValuesComments[i][j].Split(separators, StringSplitOptions.None); string[] valueLines = section.stringArrayValues[i][j].Split(separators, StringSplitOptions.None); res += indent + " /// <para>- Item " + (j + 1) + ":</para>\n"; if (valueCommentLines != null) { for (int k = 0; k < valueCommentLines.Length; ++k) { res += indent + " /// <para>// " + valueCommentLines[k] + "</para>\n"; } } for (int k = 0; k < valueLines.Length; ++k) { res += indent + " /// <para>" + valueLines[k] + "</para>\n"; } } res += indent + " /// </summary>\n" + indent + " " + section.stringArrayNames[i] + "\n" + indent + " ,\n"; } res += indent + " /// <summary>\n" + indent + " /// Total amount of string-arrays.\n" + indent + " /// </summary>\n" + indent + " Count // Should be last\n" + indent + "}\n" + "\n" + indent + "/// <summary>\n" + indent + "/// Enumeration of all plurals tags in \"Assets/Resources/res/values/" + filename + "\"\n" + indent + "/// </summary>\n" + indent + "public enum plurals\n" + indent + "{\n"; for (int i = 0; i < section.pluralsNames.Count; ++i) { string[] separators = new string[] { "\n", "\\n" }; string[] commentLines = section.pluralsComments[i] == null ? null : section.pluralsComments[i].Split(separators, StringSplitOptions.None); res += indent + " /// <summary>\n"; if (commentLines != null) { for (int j = 0; j < commentLines.Length; ++j) { res += indent + " /// <para>" + commentLines[j] + "</para>\n"; } } res += indent + " /// <para>Value:</para>\n"; for (int j = 0; j < (int)PluralsQuantity.Count; ++j) { PluralsQuantity quantity = (PluralsQuantity)j; string valueComment; string value; if ( section.pluralsValuesComments[i].TryGetValue(quantity, out valueComment) && section.pluralsValues[i].TryGetValue(quantity, out value) ) { string[] valueCommentLines = valueComment == null ? null : valueComment.Split(separators, StringSplitOptions.None); string[] valueLines = value.Split(separators, StringSplitOptions.None); res += indent + " /// <para>- " + quantity + ":</para>\n"; if (valueCommentLines != null) { for (int k = 0; k < valueCommentLines.Length; ++k) { res += indent + " /// <para>// " + valueCommentLines[k] + "</para>\n"; } } for (int k = 0; k < valueLines.Length; ++k) { res += indent + " /// <para>" + valueLines[k] + "</para>\n"; } } } res += indent + " /// </summary>\n" + indent + " " + section.pluralsNames[i] + "\n" + indent + " ,\n"; } res += indent + " /// <summary>\n" + indent + " /// Total amount of plurals.\n" + indent + " /// </summary>\n" + indent + " Count // Should be last\n" + indent + "}\n"; return res; }
/// <summary> /// Parse xml file and return SectionTokens instance with all tokens. /// </summary> /// <returns>SectionTokens instance.</returns> /// <param name="path">Path to xml file.</param> private static SectionTokens parseXmlTokens(string path) { SectionTokens res = new SectionTokens(); XmlTextReader reader = null; try { reader = new XmlTextReader(path); reader.WhitespaceHandling = WhitespaceHandling.None; bool resourcesFound = false; while (reader.Read()) { if (reader.Name == "resources") { resourcesFound = true; string lastComment = null; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Comment) { lastComment = reader.Value.Trim(); } else if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "string") { string tokenName = reader.GetAttribute("name"); if (!Utils.checkTokenName(tokenName, reader.Name, res.stringNames)) { return null; } res.stringNames.Add(tokenName); res.stringComments.Add(lastComment); res.stringValues.Add(Utils.processTokenValue(reader.ReadString())); lastComment = null; } else if (reader.Name == "string-array") { string tokenName = reader.GetAttribute("name"); if (!Utils.checkTokenName(tokenName, reader.Name, res.stringArrayNames)) { return null; } List<string> values = new List<string>(); List<string> valuesComments = new List<string>(); string lastValueComment = null; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Comment) { lastValueComment = reader.Value.Trim(); } else if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "item") { valuesComments.Add(lastValueComment); values.Add(Utils.processTokenValue(reader.ReadString())); lastValueComment = null; } else { Debug.LogError("Unexpected tag <" + reader.Name + "> found in tag <string-array> in \"Assets/Resources/res/values/strings.xml\""); return null; } } else if (reader.NodeType == XmlNodeType.EndElement) { if (reader.Name == "string-array") { break; } } } res.stringArrayNames.Add(tokenName); res.stringArrayComments.Add(lastComment); res.stringArrayValues.Add(values); res.stringArrayValuesComments.Add(valuesComments); lastComment = null; } else if (reader.Name == "plurals") { string tokenName = reader.GetAttribute("name"); if (!Utils.checkTokenName(tokenName, reader.Name, res.pluralsNames)) { return null; } Dictionary<PluralsQuantity, string> values = new Dictionary<PluralsQuantity, string>(); Dictionary<PluralsQuantity, string> valuesComments = new Dictionary<PluralsQuantity, string>(); string lastValueComment = null; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Comment) { lastValueComment = reader.Value.Trim(); } else if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "item") { PluralsQuantity quantity = PluralsQuantity.Count; // Nothing string quantityValue = reader.GetAttribute("quantity"); if (quantityValue == null) { Debug.LogError("Attribute \"quantity\" not found for tag <item> in tag <plurals> with name \"" + tokenName + "\" in \"Assets/Resources/res/values/strings.xml\""); return null; } if (quantityValue == "") { Debug.LogError("Attribute \"quantity\" empty for tag <item> in tag <plurals> with name \"" + tokenName + "\" in \"Assets/Resources/res/values/strings.xml\""); return null; } if (quantityValue == "zero") { quantity = PluralsQuantity.Zero; } else if (quantityValue == "one") { quantity = PluralsQuantity.One; } else if (quantityValue == "two") { quantity = PluralsQuantity.Two; } else if (quantityValue == "few") { quantity = PluralsQuantity.Few; } else if (quantityValue == "many") { quantity = PluralsQuantity.Many; } else if (quantityValue == "other") { quantity = PluralsQuantity.Other; } else { Debug.LogError("Unknown attribute \"quantity\" value \"" + quantityValue + "\" for tag <item> in tag <plurals> with name \"" + tokenName + "\" in \"Assets/Resources/res/values/strings.xml\""); return null; } if (!values.ContainsKey(quantity)) { valuesComments[quantity] = lastValueComment; values[quantity] = Utils.processTokenValue(reader.ReadString()); } else { Debug.LogError("Duplicate <item> tag with attribute \"quantity\" value \"" + quantityValue + "\" in tag <plurals> with name \"" + tokenName + "\" in \"Assets/Resources/res/values/strings.xml\""); return null; } lastValueComment = null; } else { Debug.LogError("Unexpected tag <" + reader.Name + "> found in tag <plurals> in \"Assets/Resources/res/values/strings.xml\""); return null; } } else if (reader.NodeType == XmlNodeType.EndElement) { if (reader.Name == "plurals") { break; } } } res.pluralsNames.Add(tokenName); res.pluralsComments.Add(lastComment); res.pluralsValues.Add(values); res.pluralsValuesComments.Add(valuesComments); lastComment = null; } else { Debug.LogError("Unexpected tag <" + reader.Name + "> found in tag <resources> in \"Assets/Resources/res/values/strings.xml\""); return null; } } } break; } } if (!resourcesFound) { Debug.LogError("Tag <resources> not found in \"Assets/Resources/res/values/strings.xml\""); return null; } } catch (Exception e) { Debug.LogError("Exception occured while parsing \"Assets/Resources/res/values/strings.xml\""); Debug.LogException(e); return null; } finally { if (reader != null) { reader.Close(); } } return res; }
/// <summary> /// Load tokens for specified section. /// </summary> /// <param name="section">Section ID.</param> /// <param name="showWarning">If set to <c>true</c> show warning about already loaded section.</param> public static void LoadSection(R.sections.SectionID section, bool showWarning) { if (tokens[(int)section + 1] == null) { tokens[(int)section + 1] = new SectionTokens(); string xmlFile = R.sections.xmlFiles[(int)section]; Dictionary<string, int>[] tokenIds = R.tokenIds[(int)section + 1]; int stringCount = tokenIds[0].Count; int stringArrayCount = tokenIds[1].Count; int pluralsCount = tokenIds[2].Count; tokens[(int)section + 1].defaultLanguage = parseXmlTokens(xmlFile, "", tokenIds, stringCount, stringArrayCount, pluralsCount); if (mLanguage != Language.Default) { string locale = AvailableLanguages.list[mLanguage]; tokens[(int)section + 1].selectedLanguage = parseXmlTokens(xmlFile, locale, tokenIds, stringCount, stringArrayCount, pluralsCount); tokens[(int)section + 1].optimize(); } mLoadedSections[section] = tokens[(int)section + 1]; } else { if (showWarning) { Debug.LogWarning("Section \"" + section + "\" already loaded"); } } }