public void MergeWith(ResourceBundle other) { // NOTE: Cultures includes InvarianCulture for root resources as well foreach (var culture in other.Cultures) { AddResources(culture, other.GetValues(culture)); } }
private static JsonResources generateJsonResources(ResourceBundle bundle, ResxToJsonConverterOptions options) { var result = new JsonResources(); // root resoruce IDictionary <string, string> baseValues = bundle.GetValues(null); JObject jBaseValues = convertValues(baseValues, options); switch (options.OutputFormat) { case OutputFormat.RequireJs: // When dealing with require.js i18n the root resource contains a "root" subnode that contains all // of the base translations and then a bunch of nodes like the following for each supported culture: // "en-US" : true // "fr" : true // ... var jRoot = new JObject(); jRoot["root"] = jBaseValues; foreach (CultureInfo culture in bundle.Cultures) { if (culture.Equals(CultureInfo.InvariantCulture)) { continue; } jRoot[culture.Name] = true; } result.BaseResources = jRoot; break; default: // In the simplest case our output format is plain vanilla json (just a kvp dictionary) result.BaseResources = jBaseValues; break; } // culture specific resources foreach (CultureInfo culture in bundle.Cultures) { if (culture.Equals(CultureInfo.InvariantCulture)) { continue; } IDictionary <string, string> values = bundle.GetValues(culture); JObject jCultureValues = convertValues(values, options); result.LocalizedResources[culture.Name] = jCultureValues; } return(result); }
/// <summary> /// Get resources from set of resx files. /// Resources are groupped in bundles for each set of resx-files with same base name (like messages.resx, messages.en.resx, message.ru.resx) /// </summary> public static IDictionary<string, ResourceBundle> GetResources(IList<string> inputFiles, ConverterLogger logger) { var fileBundles = new Dictionary<string, ResourceFileBundle>(); foreach (var filePath in inputFiles) { string fileName = Path.GetFileName(filePath); string fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName); bool isBaseFile; int idx = fileNameWithoutExt.IndexOf(".", StringComparison.InvariantCulture); // All files with the same base name form a bundle string baseName = fileNameWithoutExt; CultureInfo culture = null; ResourceFileBundle bundle; if (idx == -1) { isBaseFile = true; } else { // file name contains "." - it can culture name or something else string suffix = fileNameWithoutExt.Substring(idx + 1); culture = getCulture(suffix); if (culture != null) { // the file is a culture-specific resource file isBaseFile = false; baseName = fileNameWithoutExt.Substring(0, idx); } else { isBaseFile = true; } } if (String.IsNullOrEmpty(baseName)) { throw new Exception("Could not extract baseName from the file name: '" + fileName + "'"); } if (!fileBundles.TryGetValue(baseName, out bundle)) { bundle = new ResourceFileBundle(); fileBundles[baseName] = bundle; } if (isBaseFile) { bundle.BaseName = baseName; bundle.BaseFile = filePath; } else { bundle.AddCultureFile(culture, filePath); } } var bundles = new Dictionary<string, ResourceBundle>(); // read values from resx files grouped in bundles foreach (ResourceFileBundle fileBundle in fileBundles.Values) { if (String.IsNullOrEmpty(fileBundle.BaseFile) || String.IsNullOrEmpty(fileBundle.BaseName)) { string locFiles = null; if (fileBundle.CultureFiles.Count > 0) { locFiles = string.Join(", ", fileBundle.CultureFiles.Select(p => p.Value)); } logger.AddMsg(Severity.Error, "Ignoring localized resources without base resx-file {0}", locFiles != null ? ": " + locFiles : ""); continue; } var bundle = new ResourceBundle(fileBundle.BaseName); bundle.AddResources(null, getKeyValuePairsFromResxFile(fileBundle.BaseFile)); foreach (KeyValuePair<CultureInfo, string> pair in fileBundle.CultureFiles) { var values = getKeyValuePairsFromResxFile(pair.Value); bundle.AddResources(pair.Key, values); } bundles[fileBundle.BaseName] = bundle; } return bundles; }
public override JObject GetJsonResource(JObject jBaseValues, CultureInfo cultureInfo, ResourceBundle bundle, ResxToJsonConverterOptions options) { if (!Equals(cultureInfo, CultureInfo.InvariantCulture)) { return(jBaseValues); } // When dealing with require.js i18n the root resource contains a "root" subnode that contains all // of the base translations and then a bunch of nodes like the following for each supported culture: // "en-US" : true // "fr" : true // ... var jRoot = new JObject(); jRoot["root"] = jBaseValues; foreach (CultureInfo bundleCulture in bundle.Cultures) { if (bundleCulture.Equals(CultureInfo.InvariantCulture)) { continue; } jRoot[cultureInfo.Name] = true; } return(jRoot); }
public virtual JObject GetJsonResource(JObject jBaseValues, CultureInfo cultureInfo, ResourceBundle bundle, ResxToJsonConverterOptions options) { return(jBaseValues); }
public override JObject GetJsonResource(JObject jBaseValues, CultureInfo cultureInfo, ResourceBundle bundle, ResxToJsonConverterOptions options) { string cultureName = cultureInfo.Name; if (Equals(cultureInfo, CultureInfo.InvariantCulture)) { cultureName = options.FallbackCulture; } var jRoot = new JObject(); jRoot[cultureName] = jBaseValues; return(jRoot); }
public static ConverterLogger Convert(ResxToJsonConverterOptions options) { var logger = new ConverterLogger(); IDictionary <string, ResourceBundle> bundles = null; if (options.InputFiles.Count > 0) { bundles = ResxHelper.GetResources(options.InputFiles, logger); } if (options.InputFolders.Count > 0) { var bundles2 = ResxHelper.GetResources(options.InputFolders, options.Recursive, logger); if (bundles == null) { bundles = bundles2; } else { // join two bundles collection foreach (var pair in bundles2) { bundles[pair.Key] = pair.Value; } } } if (bundles == null || bundles.Count == 0) { logger.AddMsg(Severity.Warning, "No resx files were found"); return(logger); } logger.AddMsg(Severity.Trace, "Found {0} resx bundles", bundles.Count); if (bundles.Count > 1 && !String.IsNullOrEmpty(options.OutputFile)) { // join multiple resx resources into a single js-bundle var bundleMerge = new ResourceBundle(Path.GetFileNameWithoutExtension(options.OutputFile)); foreach (var pair in bundles) { bundleMerge.MergeWith(pair.Value); } logger.AddMsg(Severity.Trace, "As 'outputFile' option was specified all bundles were merged into single bundle '{0}'", bundleMerge.BaseName); bundles = new Dictionary <string, ResourceBundle> { { bundleMerge.BaseName, bundleMerge } }; } foreach (ResourceBundle bundle in bundles.Values) { JsonResources jsonResources = generateJsonResources(bundle, options); string baseFileName; string baseDir; if (!string.IsNullOrEmpty(options.OutputFile)) { baseFileName = Path.GetFileName(options.OutputFile); baseDir = Path.GetDirectoryName(options.OutputFile); } else { baseFileName = bundle.BaseName.ToLowerInvariant() + GetOutputFileExtension(options.OutputFormat); baseDir = options.OutputFolder; } if (string.IsNullOrEmpty(baseDir)) { baseDir = Environment.CurrentDirectory; } logger.AddMsg(Severity.Trace, "Processing '{0}' bundle (contains {1} resx files)", bundle.BaseName, bundle.Cultures.Count); string dirPath = options.OutputFormat == OutputFormat.i18next ? Path.Combine(baseDir, options.FallbackCulture) : baseDir; string outputPath = Path.Combine(dirPath, baseFileName); string jsonText = stringifyJson(jsonResources.BaseResources, options); writeOutput(outputPath, jsonText, options, logger); if (jsonResources.LocalizedResources.Count > 0) { foreach (KeyValuePair <string, JObject> pair in jsonResources.LocalizedResources) { dirPath = Path.Combine(baseDir, pair.Key); outputPath = Path.Combine(dirPath, baseFileName); jsonText = stringifyJson(pair.Value, options); writeOutput(outputPath, jsonText, options, logger); } } } return(logger); }
public void MergeWith(ResourceBundle other) { // NOTE: Cultures includes InvarianCulture for root resources as well foreach (var culture in other.Cultures) { AddResources(culture, other.GetValues(culture)); } }
private static JsonResources generateJsonResources(IResxToJsonFormatter formatter, ResourceBundle bundle, ResxToJsonConverterOptions options) { var result = new JsonResources(); // root resoruce IDictionary <string, string> baseValues = bundle.GetValues(null); JObject jBaseValues = convertValues(baseValues, options); result.BaseResources = formatter.GetJsonResource(jBaseValues, CultureInfo.InvariantCulture, bundle, options); // culture specific resources foreach (CultureInfo culture in bundle.Cultures) { if (culture.Equals(CultureInfo.InvariantCulture)) { continue; } IDictionary <string, string> values = bundle.GetValues(culture); if (options.UseFallbackForMissingTranslation) { foreach (var baseValue in baseValues) { if (!values.ContainsKey(baseValue.Key)) { values[baseValue.Key] = baseValues[baseValue.Key]; } } } JObject jCultureValues = convertValues(values, options); result.LocalizedResources[culture] = formatter.GetJsonResource(jCultureValues, culture, bundle, options); } return(result); }
public static ConverterLogger Convert(ResxToJsonConverterOptions options) { var logger = new ConverterLogger(); IDictionary<string, ResourceBundle> bundles = null; if (options.InputFiles.Count > 0) { bundles = ResxHelper.GetResources(options.InputFiles, logger); } if (options.InputFolders.Count > 0) { var bundles2 = ResxHelper.GetResources(options.InputFolders, options.Recursive, logger); if (bundles == null ) { bundles = bundles2; } else { // join two bundles collection foreach (var pair in bundles2) { bundles[pair.Key] = pair.Value; } } } if (bundles == null || bundles.Count == 0) { logger.AddMsg(Severity.Warning, "No resx files were found"); return logger; } logger.AddMsg(Severity.Trace, "Found {0} resx bundles", bundles.Count); if (bundles.Count > 1 && !String.IsNullOrEmpty(options.OutputFile)) { // join multiple resx resources into a single js-bundle var bundleMerge = new ResourceBundle(Path.GetFileNameWithoutExtension(options.OutputFile)); foreach (var pair in bundles) { bundleMerge.MergeWith(pair.Value); } logger.AddMsg(Severity.Trace, "As 'outputFile' option was specified all bundles were merged into single bundle '{0}'", bundleMerge.BaseName); bundles = new Dictionary<string, ResourceBundle> {{bundleMerge.BaseName, bundleMerge}}; } foreach (ResourceBundle bundle in bundles.Values) { JsonResources jsonResources = generateJsonResources(bundle, options); string baseFileName; string baseDir; if (!string.IsNullOrEmpty(options.OutputFile)) { baseFileName = Path.GetFileName(options.OutputFile); baseDir = Path.GetDirectoryName(options.OutputFile); } else { baseFileName = bundle.BaseName.ToLowerInvariant() + GetOutputFileExtension(options.OutputFormat); baseDir = options.OutputFolder; } if (string.IsNullOrEmpty(baseDir)) { baseDir = Environment.CurrentDirectory; } logger.AddMsg(Severity.Trace, "Processing '{0}' bundle (contains {1} resx files)", bundle.BaseName, bundle.Cultures.Count); string dirPath = options.OutputFormat == OutputFormat.i18next ? Path.Combine(baseDir, options.FallbackCulture) : baseDir; string outputPath = Path.Combine(dirPath, baseFileName); string jsonText = stringifyJson(jsonResources.BaseResources, options); writeOutput(outputPath, jsonText, options, logger); if (jsonResources.LocalizedResources.Count > 0) { foreach (KeyValuePair<string, JObject> pair in jsonResources.LocalizedResources) { dirPath = Path.Combine(baseDir, pair.Key); outputPath = Path.Combine(dirPath, baseFileName); jsonText = stringifyJson(pair.Value, options); writeOutput(outputPath, jsonText, options, logger); } } } return logger; }
private static JsonResources generateJsonResources(ResourceBundle bundle, ResxToJsonConverterOptions options) { var result = new JsonResources(); // root resoruce IDictionary<string, string> baseValues = bundle.GetValues(null); JObject jBaseValues = convertValues(baseValues, options); switch (options.OutputFormat) { case OutputFormat.RequireJs: // When dealing with require.js i18n the root resource contains a "root" subnode that contains all // of the base translations and then a bunch of nodes like the following for each supported culture: // "en-US" : true // "fr" : true // ... var jRoot = new JObject(); jRoot["root"] = jBaseValues; foreach (CultureInfo culture in bundle.Cultures) { if (culture.Equals(CultureInfo.InvariantCulture)) continue; jRoot[culture.Name] = true; } result.BaseResources = jRoot; break; default: // In the simplest case our output format is plain vanilla json (just a kvp dictionary) result.BaseResources = jBaseValues; break; } // culture specific resources foreach (CultureInfo culture in bundle.Cultures) { if (culture.Equals(CultureInfo.InvariantCulture)) continue; IDictionary<string, string> values = bundle.GetValues(culture); JObject jCultureValues = convertValues(values, options); result.LocalizedResources[culture.Name] = jCultureValues; } return result; }
/// <summary> /// Get resources from set of resx files. /// Resources are groupped in bundles for each set of resx-files with same base name (like messages.resx, messages.en.resx, message.ru.resx) /// </summary> public static IDictionary <string, ResourceBundle> GetResources(IList <string> inputFiles, ConverterLogger logger) { var fileBundles = new Dictionary <string, ResourceFileBundle>(); foreach (var filePath in inputFiles) { string fileName = Path.GetFileName(filePath); string fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName); bool isBaseFile; int idx = fileNameWithoutExt.IndexOf(".", StringComparison.InvariantCulture); // All files with the same base name form a bundle string baseName = fileNameWithoutExt; CultureInfo culture = null; ResourceFileBundle bundle; if (idx == -1) { isBaseFile = true; } else { // file name contains "." - it can culture name or something else string suffix = fileNameWithoutExt.Substring(idx + 1); culture = getCulture(suffix); if (culture != null) { // the file is a culture-specific resource file isBaseFile = false; baseName = fileNameWithoutExt.Substring(0, idx); } else { isBaseFile = true; } } if (String.IsNullOrEmpty(baseName)) { throw new Exception("Could not extract baseName from the file name: '" + fileName + "'"); } if (!fileBundles.TryGetValue(baseName, out bundle)) { bundle = new ResourceFileBundle(); fileBundles[baseName] = bundle; } if (isBaseFile) { bundle.BaseName = baseName; bundle.BaseFile = filePath; } else { bundle.AddCultureFile(culture, filePath); } } var bundles = new Dictionary <string, ResourceBundle>(); // read values from resx files grouped in bundles foreach (ResourceFileBundle fileBundle in fileBundles.Values) { if (String.IsNullOrEmpty(fileBundle.BaseFile) || String.IsNullOrEmpty(fileBundle.BaseName)) { string locFiles = null; if (fileBundle.CultureFiles.Count > 0) { locFiles = string.Join(", ", fileBundle.CultureFiles.Select(p => p.Value)); } logger.AddMsg(Severity.Error, "Ignoring localized resources without base resx-file {0}", locFiles != null ? ": " + locFiles : ""); continue; } var bundle = new ResourceBundle(fileBundle.BaseName); bundle.AddResources(null, getKeyValuePairsFromResxFile(fileBundle.BaseFile)); foreach (KeyValuePair <CultureInfo, string> pair in fileBundle.CultureFiles) { var values = getKeyValuePairsFromResxFile(pair.Value); bundle.AddResources(pair.Key, values); } bundles[fileBundle.BaseName] = bundle; } return(bundles); }