/// <summary> /// Write the localizable key-value pairs /// </summary> /// <param name="options"></param> internal static void Write(LocBamlOptions options) { InputBamlStreamList bamlStreamList = new InputBamlStreamList(options); using (ITranslationWriter writer = options.GetTranslationWriter()) { options.WriteLine(StringLoader.Get("WriteBamlValues")); for (int i = 0; i < bamlStreamList.Count; i++) { options.Write(" "); options.Write(StringLoader.Get("ProcessingBaml", bamlStreamList[i].Name)); // Search for comment file in the same directory. The comment file has the extension to be // "loc". string commentFile = Path.ChangeExtension(bamlStreamList[i].Name, "loc"); TextReader commentStream = null; try { if (File.Exists(commentFile)) { commentStream = new StreamReader(commentFile); } // create the baml localizer BamlLocalizer mgr = new BamlLocalizer( bamlStreamList[i].Stream, new BamlLocalizabilityByReflection(options.Assemblies), commentStream ); // extract localizable resource from the baml stream BamlLocalizationDictionary dict = mgr.ExtractResources(); // write out each resource foreach (DictionaryEntry entry in dict) { BamlLocalizableResourceKey key = (BamlLocalizableResourceKey)entry.Key; BamlLocalizableResource resource = (BamlLocalizableResource)entry.Value; writer.WriteResource(bamlStreamList[i].Name, LocBamlConst.ResourceKeyToString(key), resource); } options.WriteLine(StringLoader.Get("Done")); } finally { if (commentStream != null) { commentStream.Close(); } } } // close all the baml input streams, output stream is closed by writer. bamlStreamList.Close(); } }
internal ResourceTextReader(TranslationFileType fileType, Stream stream) { _delimiter = LocBamlConst.GetDelimiter(fileType); if (stream == null) { throw new ArgumentNullException("stream"); } _reader = new StreamReader(stream); }
//----------------------------------------- // private function dealing with naming //----------------------------------------- // return the local output file name, i.e. without directory private static string GetOutputFileName(LocBamlOptions options) { string outputFileName; string inputFileName = Path.GetFileName(options.Input); switch (options.InputType) { case FileType.BAML: { return(inputFileName); } case FileType.EXE: { inputFileName = inputFileName.Remove(inputFileName.LastIndexOf('.')) + ".resources.dll"; return(inputFileName); } case FileType.DLL: { return(inputFileName); } case FileType.RESOURCES: { // get the output file name outputFileName = inputFileName; // get to the last dot separating filename and extension int lastDot = outputFileName.LastIndexOf('.'); int secondLastDot = outputFileName.LastIndexOf('.', lastDot - 1); if (secondLastDot > 0) { string cultureName = outputFileName.Substring(secondLastDot + 1, lastDot - secondLastDot - 1); if (LocBamlConst.IsValidCultureName(cultureName)) { string extension = outputFileName.Substring(lastDot); string frontPart = outputFileName.Substring(0, secondLastDot + 1); outputFileName = frontPart + options.CultureInfo.Name + extension; } } return(outputFileName); } default: { throw new NotSupportedException(); } } }
//------------------------------- // constructor //------------------------------- internal ResourceTextWriter(FileType fileType, Stream output) { _delimiter = LocBamlConst.GetDelimiter(fileType); if (output == null) { throw new ArgumentNullException("output"); } // show utf8 byte order marker UTF8Encoding encoding = new UTF8Encoding(true); _writer = new StreamWriter(output, encoding); _firstColumn = true; }
internal TranslationDictionariesReader(XliffObject xliff) { // hash key is case insensitive strings _table = new Hashtable(); foreach (File file in xliff.Files) { string bamlName = file.Original; // get the dictionary BamlLocalizationDictionary dictionary = this[bamlName]; if (dictionary == null) { // we create one if it is not there yet. dictionary = new BamlLocalizationDictionary(); this[bamlName] = dictionary; } Body body = file.Body; // There should only be one group, but go through any that exist for good measure foreach (Group group in body.Groups) { foreach (TranslationUnit transUnit in group.TranslationUnits) { string key = transUnit.Id; BamlLocalizableResourceKey resourceKey = LocBamlConst.StringToResourceKey(key); BamlLocalizableResource resource = new BamlLocalizableResource(); resource.Category = (LocalizationCategory)StringCatConverter.ConvertFrom(transUnit.ResourceType); /* * resource.Readable = (bool)BoolTypeConverter.ConvertFrom(reader.GetColumn(3)); * resource.Modifiable = (bool)BoolTypeConverter.ConvertFrom(reader.GetColumn(4)); */ Note comment = transUnit.Notes.FirstOrDefault(n => n.From == "MultilingualBuild"); if (comment != null) { resource.Comments = comment.Text; } resource.Content = transUnit.Target.Content ?? string.Empty; dictionary.Add(resourceKey, resource); } } } }
/// <summary> /// Write the localizable key-value pairs /// </summary> /// <param name="options"></param> internal static void Write(LocBamlOptions options) { Stream output = new FileStream(options.Output, FileMode.Create); InputBamlStreamList bamlStreamList = new InputBamlStreamList(options); using (ResourceTextWriter writer = new ResourceTextWriter(options.TranslationFileType, output)) { options.WriteLine(StringLoader.Get("WriteBamlValues")); for (int i = 0; i < bamlStreamList.Count; i++) { options.Write(" "); options.Write(StringLoader.Get("ProcessingBaml", bamlStreamList[i].Name)); // Search for comment file in the same directory. The comment file has the extension to be // "loc". string commentFile = Path.ChangeExtension(bamlStreamList[i].Name, "loc"); TextReader commentStream = null; try { if (File.Exists(commentFile)) { commentStream = new StreamReader(commentFile); } // create the baml localizer BamlLocalizer mgr = new BamlLocalizer( bamlStreamList[i].Stream, new BamlLocalizabilityByReflection(options.Assemblies), commentStream ); // extract localizable resource from the baml stream BamlLocalizationDictionary dict = mgr.ExtractResources(); // write out each resource foreach (DictionaryEntry entry in dict) { // column 1: baml stream name writer.WriteColumn(bamlStreamList[i].Name); BamlLocalizableResourceKey key = (BamlLocalizableResourceKey)entry.Key; BamlLocalizableResource resource = (BamlLocalizableResource)entry.Value; // column 2: localizable resource key writer.WriteColumn(LocBamlConst.ResourceKeyToString(key)); // column 3: localizable resource's category writer.WriteColumn(resource.Category.ToString()); // column 4: localizable resource's readability writer.WriteColumn(resource.Readable.ToString()); // column 5: localizable resource's modifiability writer.WriteColumn(resource.Modifiable.ToString()); // column 6: localizable resource's localization comments writer.WriteColumn(resource.Comments); // column 7: localizable resource's content writer.WriteColumn(resource.Content); // Done. finishing the line writer.EndLine(); } options.WriteLine(StringLoader.Get("Done")); } finally { if (commentStream != null) { commentStream.Close(); } } } // close all the baml input streams, output stream is closed by writer. bamlStreamList.Close(); } }
/// <summary> /// Constructor /// </summary> /// <param name="reader">resoure text reader that reads CSV or a tab-separated txt file</param> internal TranslationDictionariesReader(ResourceTextReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } // hash key is case insensitive strings _table = new Hashtable(); // we read each Row int rowNumber = 0; while (reader.ReadRow()) { rowNumber++; // field #1 is the baml name. string bamlName = reader.GetColumn(0); // it can't be null if (bamlName == null) { throw new ApplicationException(StringLoader.Get("EmptyRowEncountered")); } if (string.IsNullOrEmpty(bamlName)) { // allow for comment lines in csv file. // each comment line starts with ",". It will make the first entry as String.Empty. // and we will skip the whole line. continue; // if the first column is empty, take it as a comment line } // field #2: key to the localizable resource string key = reader.GetColumn(1); if (key == null) { throw new ApplicationException(StringLoader.Get("NullBamlKeyNameInRow")); } BamlLocalizableResourceKey resourceKey = LocBamlConst.StringToResourceKey(key); // get the dictionary BamlLocalizationDictionary dictionary = this[bamlName]; if (dictionary == null) { // we create one if it is not there yet. dictionary = new BamlLocalizationDictionary(); this[bamlName] = dictionary; } BamlLocalizableResource resource; // the rest of the fields are either all null, // or all non-null. If all null, it means the resource entry is deleted. // get the string category string categoryString = reader.GetColumn(2); if (categoryString == null) { // it means all the following fields are null starting from column #3. resource = null; } else { // the rest must all be non-null. // the last cell can be null if there is no content for (int i = 3; i < 6; i++) { if (reader.GetColumn(i) == null) { throw new Exception(StringLoader.Get("InvalidRow")); } } // now we know all are non-null. let's try to create a resource resource = new BamlLocalizableResource(); // field #3: Category resource.Category = (LocalizationCategory)StringCatConverter.ConvertFrom(categoryString); // field #4: Readable resource.Readable = (bool)BoolTypeConverter.ConvertFrom(reader.GetColumn(3)); // field #5: Modifiable resource.Modifiable = (bool)BoolTypeConverter.ConvertFrom(reader.GetColumn(4)); // field #6: Comments resource.Comments = reader.GetColumn(5); // field #7: Content resource.Content = reader.GetColumn(6); // in case content being the last column, consider null as empty. if (resource.Content == null) { resource.Content = string.Empty; } // field > #7: Ignored. } // at this point, we are good. // add to the dictionary. dictionary.Add(resourceKey, resource); } }