From 69d86cfcf241d1a36900287bdabccbf02318b527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 19 Apr 2014 20:14:42 +0200 Subject: [PATCH] add automated language string extraction to utility --- OpenRA.Game/Exts.cs | 5 ++ OpenRA.Game/ObjectCreator.cs | 8 ++- OpenRA.Utility/ExtractLanguageStrings.cs | 68 ++++++++++++++++++++++++ OpenRA.Utility/OpenRA.Utility.csproj | 1 + OpenRA.Utility/Program.cs | 5 +- 5 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 OpenRA.Utility/ExtractLanguageStrings.cs diff --git a/OpenRA.Game/Exts.cs b/OpenRA.Game/Exts.cs index 8ad658b828..811fe192f2 100644 --- a/OpenRA.Game/Exts.cs +++ b/OpenRA.Game/Exts.cs @@ -20,6 +20,11 @@ namespace OpenRA { public static class Exts { + public static bool IsUppercase(this string str) + { + return string.Compare(str.ToUpperInvariant(), str, false) == 0; + } + public static string F(this string fmt, params object[] args) { return string.Format(fmt, args); diff --git a/OpenRA.Game/ObjectCreator.cs b/OpenRA.Game/ObjectCreator.cs index db14e3f0ec..5a575bbba1 100755 --- a/OpenRA.Game/ObjectCreator.cs +++ b/OpenRA.Game/ObjectCreator.cs @@ -111,9 +111,13 @@ namespace OpenRA public IEnumerable GetTypesImplementing() { var it = typeof(T); + return GetTypes().Where(t => t != it && it.IsAssignableFrom(t)); + } + + public IEnumerable GetTypes() + { return assemblies.Select(ma => ma.First).Distinct() - .SelectMany(ma => ma.GetTypes() - .Where(t => t != it && it.IsAssignableFrom(t))); + .SelectMany(ma => ma.GetTypes()); } [AttributeUsage(AttributeTargets.Constructor)] diff --git a/OpenRA.Utility/ExtractLanguageStrings.cs b/OpenRA.Utility/ExtractLanguageStrings.cs new file mode 100644 index 0000000000..b620657bf7 --- /dev/null +++ b/OpenRA.Utility/ExtractLanguageStrings.cs @@ -0,0 +1,68 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; + +namespace OpenRA.Utility +{ + public class ExtractLanguageStrings + { + [Desc("MOD", "Extract translatable strings that are not yet localized and update chrome layout.")] + public static void FromMod(string[] args) + { + var mod = args[1]; + Game.modData = new ModData(mod); + Game.modData.RulesetCache.LoadDefaultRules(); + + var types = Game.modData.ObjectCreator.GetTypes(); + var translatableFields = types.SelectMany(t => t.GetFields()) + .Where(f => f.HasAttribute()).Distinct(); + + foreach (var filename in Game.modData.Manifest.ChromeLayout) + { + Console.WriteLine("# {0}:", filename); + var yaml = MiniYaml.FromFile(filename); + ExtractLanguageStrings.FromChromeLayout(ref yaml, null, + translatableFields.Select(t => t.Name).Distinct(), null); + using (var file = new StreamWriter(filename)) + file.WriteLine(yaml.WriteToString()); + } + + // TODO: Properties can also be translated. + } + + public static void FromChromeLayout(ref List nodes, MiniYamlNode parent, IEnumerable translatables, string container) + { + var parentNode = parent != null ? parent.Key.Split('@') : null; + var parentType = parent != null ? parentNode.First() : null; + var parentLabel = parent != null ? parentNode.Last() : null; + + if ((parentType == "Background" || parentType == "Container") && parentLabel.IsUppercase()) + container = parentLabel; + + foreach (var node in nodes) + { + var alreadyTranslated = node.Value.Value != null && node.Value.Value.Contains('@'); + if (translatables.Contains(node.Key) && !alreadyTranslated) + { + var translationKey = "{0}-{1}-{2}".F(container.Replace('_', '-'), parentLabel.Replace('_', '-'), node.Key.ToUpper()); + Console.WriteLine("\t{0}: {1}", translationKey , node.Value.Value); + node.Value.Value = "@{0}@".F(translationKey); + } + + FromChromeLayout(ref node.Value.Nodes, node, translatables, container); + } + } + + } +} diff --git a/OpenRA.Utility/OpenRA.Utility.csproj b/OpenRA.Utility/OpenRA.Utility.csproj index c06279d850..61464771f7 100644 --- a/OpenRA.Utility/OpenRA.Utility.csproj +++ b/OpenRA.Utility/OpenRA.Utility.csproj @@ -80,6 +80,7 @@ + diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index f04e9700dc..5f8a7ec73f 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -33,7 +33,8 @@ namespace OpenRA.Utility { "--map-upgrade-v5", Command.UpgradeV5Map }, { "--upgrade-map", UpgradeRules.UpgradeMap }, { "--upgrade-mod", UpgradeRules.UpgradeMod }, - { "--map-import", Command.ImportLegacyMap } + { "--map-import", Command.ImportLegacyMap }, + { "--extract-language-strings", ExtractLanguageStrings.FromMod } }; static void Main(string[] args)