Skip to content

Instantly share code, notes, and snippets.

@igorkulman
Last active February 10, 2016 12:40
Show Gist options
  • Save igorkulman/53a29b6e2143cac1ec8a to your computer and use it in GitHub Desktop.
Save igorkulman/53a29b6e2143cac1ec8a to your computer and use it in GitHub Desktop.
<local:LocalizedStrings x:Key="S" />
public partial class AppResources
{
private static readonly ResourceLoader _resourceLoader;
static AppResources()
{
_resourceLoader=new ResourceLoader();
}
internal AppResources()
{
}
}
public string Game => _resourceLoader.GetString("Game");
var text = AppResources.Game;
//directories representing the versions (e.g. 1.0, 1.0)
var dirs = Directory.GetDirectories(@"..\..\..\SecretProject-localization\export");
//the newest version
var version = dirs.Select(l => new Version(l.Split(Path.DirectorySeparatorChar).Last())).Max();
//all the localization keys
var keys = new HashSet<string>();
//each JSON file represents string for one language
var files = Directory.GetFiles(@"..\..\..\SecretProject-localization\export\"+ version).Where(l=>l.EndsWith(".json"));
foreach (var file in files)
{
//RESW XML header
var sb = new StringBuilder();
sb.AppendLine(
"<?xml version=\"1.0\" encoding=\"utf-8\"?><root> <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\"> <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" /> <xsd:element name=\"root\" msdata:IsDataSet=\"true\"> <xsd:complexType> <xsd:choice maxOccurs=\"unbounded\"> <xsd:element name=\"metadata\"> <xsd:complexType> <xsd:sequence> <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" /> </xsd:sequence> <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" /> <xsd:attribute name=\"type\" type=\"xsd:string\" /> <xsd:attribute name=\"mimetype\" type=\"xsd:string\" /> <xsd:attribute ref=\"xml:space\" /> </xsd:complexType> </xsd:element> <xsd:element name=\"assembly\"> <xsd:complexType> <xsd:attribute name=\"alias\" type=\"xsd:string\" /> <xsd:attribute name=\"name\" type=\"xsd:string\" /> </xsd:complexType> </xsd:element> <xsd:element name=\"data\"> <xsd:complexType> <xsd:sequence> <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" /> <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" /> </xsd:sequence> <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" /> <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" /> <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" /> <xsd:attribute ref=\"xml:space\" /> </xsd:complexType> </xsd:element> <xsd:element name=\"resheader\"> <xsd:complexType> <xsd:sequence> <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" /> </xsd:sequence> <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name=\"resmimetype\"> <value>text/microsoft-resx</value> </resheader> <resheader name=\"version\"> <value>2.0</value> </resheader> <resheader name=\"reader\"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name=\"writer\"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader>");
//read and parse the JSON file
var content = File.ReadAllText(file);
var j = JObject.Parse(content);
IDictionary<string, JToken> strings = (JObject)j["strings"];
//get all the localization keys
foreach (var key in strings.Keys.Distinct())
{
var safeKey = key.Replace(".", "_DOT_").Replace("-", "_DASH_");
//add an XML entry to the RESW file
sb.AppendLine($"<data name=\"{safeKey}\" xml:space=\"preserve\">");
sb.AppendLine($"<value>{strings[key].ToString().Replace("&","&amp;")}</value>");
sb.AppendLine("</data>");
//save the key for later use
keys.Add(safeKey);
}
//end the RESW file
sb.AppendLine("</root>");
var pathsParts = file.Split(Path.DirectorySeparatorChar);
var filenameParts = pathsParts.Last().Split('.');
//write the RESW content to a correct file on the disk
var suffix = filenameParts[0];
var filename = @"..\..\..\SecretProject\strings\"+suffix+@"\Resources.resw";
File.WriteAllText(filename, sb.ToString());
}
var sbx = new StringBuilder();
sbx.AppendLine("namespace SecretProject.Localization");
sbx.AppendLine("{");
sbx.AppendLine(" public partial class AppResources");
sbx.AppendLine(" {");
foreach (var key in keys)
{
sbx.AppendLine($" public string {key} => _resourceLoader.GetString(\"{key}\");");
}
sbx.AppendLine(" public string GetString(string key) => _resourceLoader.GetString(key);");
sbx.AppendLine(" }");
sbx.AppendLine("}");
File.WriteAllText(@"..\..\..\SecretProject\Localization\AppResources.strings.cs", sbx.ToString());
public class LocalizedStrings
{
public AppResources LocalizedResources { get; }
public LocalizedStrings()
{
LocalizedResources = new AppResources();
}
}
<TextBlock Text="{Binding LocalizedResources.Game, Source={StaticResource S}}" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment