public POStringLocalizer(CultureInfo culture, string contextId, Func <CultureInfo, bool, POCatalog> getCatalogForCulture, IOptions <TextLocalizationOptions> localizationOptions) : base(contextId, localizationOptions) { _catalog = getCatalogForCulture(culture, false); _parentCultureCatalog = getCatalogForCulture(culture.Parent, true); _fallBackCatalog = getCatalogForCulture(new CultureInfo(Settings.NeutralCulture), false); _getCatalogForCulture = getCatalogForCulture; }
private POCatalog ProcessCatalog(POCatalog inputCatalog) { var outputCatalog = new POCatalog() { HeaderComments = inputCatalog.HeaderComments, Headers = inputCatalog.Headers, Encoding = inputCatalog.Encoding, Language = Culture, PluralFormCount = inputCatalog.PluralFormCount, PluralFormSelector = inputCatalog.PluralFormSelector }; // Entries foreach (var entry in inputCatalog.Values) { switch (entry) { case POSingularEntry singularEntry: outputCatalog.Add(TransformSingularEntry(singularEntry)); break; case POPluralEntry plural: outputCatalog.Add(TransformPluralEntry(plural)); break; default: throw new NotSupportedException($"Unsupported PO entry type {entry.GetType()}"); } } return(outputCatalog); }
bool TryGetTranslationCore(POKey key, int pluralCount, out string value, POCatalog catalog = null) { if (catalog == null) { catalog = Catalog; } if (catalog != null) { var translation = catalog.GetTranslation(key, pluralCount); if (translation != null) { value = translation; return(true); } else { translation = ParentCultureCatalog?.GetTranslation(key, pluralCount); if (translation != null) { value = translation; return(true); } else if (Options.Value.FallBackNeutralCulture && catalog.GetCultureName() != Settings.NeutralCulture) { return(TryGetTranslationCore(key, pluralCount, out value, FallBackCatalog)); } } } value = null; return(false); }
private void Generate_LineBreak_Core(string id, params string[] lines) { var generator = new POGenerator(new POGeneratorSettings { IgnoreEncoding = true, SkipInfoHeaders = true, }); var catalog = new POCatalog { Encoding = "UTF-8" }; var entry = new POSingularEntry(new POKey(id)); catalog.Add(entry); var sb = new StringBuilder(); generator.Generate(sb, catalog); var expected = new List <string>(); expected.Add(@"msgid """""); expected.AddRange(lines); expected.Add(@"msgstr """""); IEnumerable <string> actual = sb.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None).Skip(5).Take(lines.Length + 2); Assert.Equal(expected, actual); }
void CheckItems(POCatalog catalog, bool expectComments) { var key1 = new POKey("{0} hour to midnight", "{0} hours to midnight", "Home"); var key2 = new POKey($"Here is an example of how one might continue a very long string{Environment.NewLine}" + $"for the common case the string represents multi-line output.{Environment.NewLine}"); Assert.Equal(2, catalog.Count); Assert.Contains(key1, catalog.Keys); Assert.Contains(key2, catalog.Keys); Assert.Equal(2, catalog[key1].Count); Assert.Equal("Translation of {0} hour to midnight", catalog.GetTranslation(key1, 1)); Assert.Equal("Translation of {0} hours to midnight", catalog[key1][1]); Assert.Equal("Translation of {0} hour to midnight", catalog.GetTranslation(key1, 1)); Assert.Equal("Translation of {0} hours to midnight", catalog.GetTranslation(key1, 2)); Assert.Equal(1, catalog[key2].Count); Assert.Equal("Some translation of long text", catalog[key2][0]); if (expectComments) { Assert.Equal(6, catalog[key1].Comments.Count); Assert.Equal(0, catalog[key2].Comments.Count); var comments = catalog[key1].Comments; Assert.Equal(POCommentKind.Translator, comments[0].Kind); Assert.Equal("some translator comment", ((POTranslatorComment)comments[0]).Text); Assert.Equal(POCommentKind.Extracted, comments[1].Kind); Assert.Equal("some extracted comment", ((POExtractedComment)comments[1]).Text); Assert.Equal(POCommentKind.Reference, comments[2].Kind); var references = ((POReferenceComment)comments[2]).References; Assert.Equal(1, references.Count); Assert.Equal("/Views/Home/Index.cshtml", references[0].FilePath); Assert.Equal(8, references[0].Line); Assert.Equal(POCommentKind.Flags, comments[3].Kind); var flags = ((POFlagsComment)comments[3]).Flags; Assert.Equal(2, flags.Count); Assert.Contains("fuzzy", flags); Assert.Contains("csharp-format", flags); Assert.Equal(POCommentKind.PreviousValue, comments[4].Kind); Assert.Equal(POIdKind.Id, ((POPreviousValueComment)comments[4]).IdKind); Assert.Equal("{0} hour to midnite", ((POPreviousValueComment)comments[4]).Value); Assert.Equal(POCommentKind.PreviousValue, comments[5].Kind); Assert.Equal(POIdKind.PluralId, ((POPreviousValueComment)comments[5]).IdKind); Assert.Equal("{0} hours to midnite", ((POPreviousValueComment)comments[5]).Value); } else { Assert.Null(catalog[key1].Comments); Assert.Null(catalog[key2].Comments); } }
private static void LoadLocaleFromWeb() { using (WebClient wc = new WebClient()) { string poText = wc.DownloadString(currentLocale); POParser parser = new POParser(); poCatalog = parser.Parse(poText).Catalog; } }
private void AddToCatalog(POCatalog catalog, ExtractedText extractedEntry) { var catalogKey = new POKey(extractedEntry.Japanese); var catalogEntry = new POSingularEntry(catalogKey) { Comments = new List <POComment> { new POReferenceComment { References = new POSourceReference[] { new POSourceReference($"{extractedEntry.Source}", extractedEntry.SourceLine) } } }, }; if (!string.IsNullOrEmpty(extractedEntry.English)) { catalogEntry.Translation = extractedEntry.English.Trim(' '); } var comment = extractedEntry.Comment ?? ""; // If we have Korean text add it to the comment as well. This gives us multiple strings to throw at a // machine translator to hopefully get better context. if (!string.IsNullOrEmpty(extractedEntry.Korean) && extractedEntry.Korean != extractedEntry.Japanese && !comment.Contains("Korean Text: ", StringComparison.Ordinal)) { if (comment.Length > 0) { comment += "; "; } // The comment we save the Korean text in can't contain new lines, tabs are just for visual convenience comment += "Korean Text: '" + extractedEntry.Korean.Replace("\r", "\\r", StringComparison.Ordinal) .Replace("\n", "\\n", StringComparison.Ordinal) .Replace("\t", "\\t", StringComparison.Ordinal) + "'"; } if (!string.IsNullOrEmpty(comment)) { catalogEntry.Comments.Add(new POTranslatorComment() { Text = comment }); } catalog.Add(catalogEntry); }
private void LoadCatalog(Stream textStream) { var result = _parser.Parse(textStream); if (result.Success) { _catalog = result.Catalog; _replacedEntries = new string[_catalog.Count]; textStream.Close(); } else { //Err } }
public void ParseFull() { var parser = new POParser(); POParseResult result; using (var ms = new MemoryStream(Resources.SamplePO)) result = parser.Parse(ms); Assert.True(result.Success); POCatalog catalog = result.Catalog; CheckHeader(catalog, expectComments: true, expectInfoHeaders: true, expectOrderedHeaders: false); CheckItems(catalog, expectComments: true); }
private static void WriteCatalog(POCatalog catalog, string outputFile, DateTime versionDate) { if (File.Exists(outputFile)) { File.Delete(outputFile); } var generator = new POGenerator(new POGeneratorSettings()); using var outStream = File.Open(outputFile, FileMode.OpenOrCreate); using var writer = new StreamWriter(outStream, Encoding.UTF8); // We only store the date when generating catalog.Headers["PO-Revision-Date"] = string.Format("{0:yyyy-MM-dd 12:00-0400}", versionDate); generator.Generate(writer, catalog); }
public void ParseSkipInfoHeaders() { var parser = new POParser(new POParserSettings { SkipInfoHeaders = true }); var input = new StreamReader(new MemoryStream(Resources.SamplePO)); POParseResult result = parser.Parse(input); Assert.True(result.Success); POCatalog catalog = result.Catalog; CheckHeader(catalog, expectComments: true, expectInfoHeaders: false, expectOrderedHeaders: false); CheckItems(catalog, expectComments: true); }
void CheckHeader(POCatalog catalog, bool expectComments, bool expectInfoHeaders) { if (expectInfoHeaders) { Assert.Equal(12, catalog.Headers.Count); Assert.Equal("8bit", catalog.Headers["Content-Transfer-Encoding"]); Assert.Equal("text/plain; charset=UTF-8", catalog.Headers["Content-Type"]); Assert.Equal("", catalog.Headers["Language-Team"]); Assert.Equal("nplurals=2; plural=(n != 1);", catalog.Headers["Plural-Forms"]); Assert.Equal("", catalog.Headers["PO-Revision-Date"]); Assert.Equal("2018-06-22 07:01+0200", catalog.Headers["POT-Creation-Date"]); Assert.Equal("", catalog.Headers["Project-Id-Version"]); Assert.Equal("", catalog.Headers["Report-Msgid-Bugs-To"]); Assert.Equal("1.0", catalog.Headers["MIME-Version"]); Assert.Equal("Poedit 2.0.8", catalog.Headers["X-Generator"]); Assert.Equal("", catalog.Headers["Last-Translator"]); Assert.Equal("en_US", catalog.Headers["Language"]); } else { Assert.Null(catalog.Headers); } Assert.Equal("UTF-8", catalog.Encoding); Assert.Equal("en_US", catalog.Language); Assert.Equal(2, catalog.PluralFormCount); Assert.Equal("(n != 1)", catalog.PluralFormSelector); Assert.Equal(0, catalog.GetPluralFormIndex(1)); Assert.Equal(1, catalog.GetPluralFormIndex(2)); Assert.Equal(1, catalog.GetPluralFormIndex(5)); if (expectComments) { Assert.Equal(1, catalog.HeaderComments.Count); var comments = catalog.HeaderComments; Assert.Equal(POCommentKind.Translator, comments[0].Kind); Assert.Equal("header comment", ((POTranslatorComment)comments[0]).Text); } else { Assert.Null(catalog.HeaderComments); } }
public void ParseHeaderOnly() { var parser = new POParser(new POParserSettings { ReadHeaderOnly = true }); POParseResult result; using (var ms = new MemoryStream(Resources.SamplePO)) result = parser.Parse(ms); Assert.True(result.Success); POCatalog catalog = result.Catalog; CheckHeader(catalog, expectComments: true, expectInfoHeaders: true, expectOrderedHeaders: false); Assert.Empty(catalog); }
public IActionResult Export() { byte[] archiveFile; var generator = new POGenerator(); using (var archiveStream = new MemoryStream()) { using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true)) { foreach (var textCatalog in localizationProvider.TextCatalogs) { var entries = Enumerable.AsEnumerable <IPOEntry>(textCatalog.Value); var contextIds = entries.Select(i => i.Key.ContextId).Distinct(); foreach (var contextId in contextIds) { var filteredCatalog = new POCatalog(entries.Where(entry => entry.Key.ContextId == contextId)) { Encoding = textCatalog.Value.Encoding, PluralFormCount = textCatalog.Value.PluralFormCount, PluralFormSelector = textCatalog.Value.PluralFormSelector, Language = textCatalog.Value.Language, Headers = new Dictionary <string, string> { { "X-Generator", "BlazorBoilerplate" }, } }; var zipEntry = archive.CreateEntry($"{contextId}-{textCatalog.Key}.po"); using var entryStream = zipEntry.Open(); generator.Generate(entryStream, filteredCatalog); } } } archiveFile = archiveStream.ToArray(); } return(File(archiveFile, MediaTypeNames.Application.Zip, "PO.zip")); }
private void WriteCatalog(TextWriter writer, POCatalog catalog, CultureInfo?culture) { var now = DateTimeOffset.Now; try { catalog.Encoding = Encoding.GetEncoding(writer.Encoding.CodePage).BodyName; } catch (NotSupportedException) { catalog.Encoding = "(n/a)"; } if (culture != null) { catalog.Language = culture.Name.Replace('-', '_'); if (PluralFormHelper.TryGetPluralForm(culture, out var pluralFormCount, out var pluralFormSelector)) { (catalog.PluralFormCount, catalog.PluralFormSelector) = (pluralFormCount, pluralFormSelector); for (int i = 0, n = catalog.Count; i < n; i++) { EnsureTranslationCount(catalog[i], pluralFormCount); } }
public static void ExportAll(string directory) { var languageSources = Resources.FindObjectsOfTypeAll <I2.Loc.LanguageSourceAsset>(); var gen = new POGenerator(); foreach (var source in languageSources) { var fullName = source.name; var shortName = fullName.Replace("Languages", ""); POCatalog catalog = null; if (shortName == "Dialogue" || shortName == "ButtonsImages") { continue; } int engIndex = source.mSource.GetLanguageIndex("English"); catalog = LanguageSourceToCatalog(source, engIndex); var catalogPath = Path.Combine(directory, shortName + ".pot"); using (var file = File.Create(catalogPath)) using (var writer = new StreamWriter(file)) { gen.Generate(writer, catalog); } } // Manually generate dialogue catalog for additional infos // Actor, conversant, conversation context var db = Resources.FindObjectsOfTypeAll <DialogueDatabase>()[0]; var dialogueCatalog = GetDialogueCatalog(db); var dialogueCatalogPath = Path.Combine(directory, "Dialogue.pot"); using (var file = File.Create(dialogueCatalogPath)) using (var writer = new StreamWriter(file)) { gen.Generate(writer, dialogueCatalog); } }
/// <summary> /// Creates a catalog for a translations dictionary for a given encoding and language /// </summary> /// <param name="fileEncoding">File encoding</param> /// <param name="htmlTextKeys">A list of translations</param> /// <param name="translationsLanguage">Translations language</param> /// <returns></returns> public POCatalog CreateCatalog(Encoding fileEncoding, IList <string> htmlTextKeys, string translationsLanguage) { var catalog = new POCatalog { // Setting Required Headers Encoding = fileEncoding.WebName, Language = translationsLanguage, // Setting Custom Headers Headers = CreateHeaders() }; foreach (var htmlTextKey in htmlTextKeys) { var poKey = new POKey(htmlTextKey); var poEntry = new POSingularEntry(poKey); catalog.Add(poEntry); } return(catalog); }
public static void LoadLocaleFromFile() { string poFile = currentLocale + ".po"; string moFile = currentLocale + ".mo"; if (File.Exists(poFile)) { using (Stream stream = File.OpenRead(poFile)) { POParser parser = new POParser(); poCatalog = parser.Parse(stream).Catalog; } } else if (File.Exists(moFile)) { using (Stream stream = File.OpenRead(moFile)) { moCatalog = new Catalog(stream, new CultureInfo(currentLocale.Replace('_', '-'))); } } else { byte[] embeddedMo = (byte[])Properties.Resources.ResourceManager.GetObject( "locale_" + currentLocale); if (embeddedMo == null) { return; } using (Stream stream = new MemoryStream(embeddedMo)) { moCatalog = new Catalog(stream, new CultureInfo(currentLocale.Replace('_', '-'))); } } }
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { var translationResult = (TranslationResult)context.Object; var poCatalog = new POCatalog(); poCatalog.Language = translationResult.Language; poCatalog.Encoding = "UTF-8"; translationResult.Entries.ForEach(entry => { var poKey = new POKey(entry.Key, contextId: entry.Collection); var poEntry = new POSingularEntry(poKey); poEntry.Translation = entry.Value; poCatalog.Add(poEntry); }); var poGenerator = new POGenerator(); var memoryStream = new MemoryStream(); poGenerator.Generate(memoryStream, poCatalog, Encoding.UTF8); memoryStream.Position = 0; await memoryStream.CopyToAsync(context.HttpContext.Response.Body); }
/// <summary> /// Creates a catalog for a translations dictionary for a given encoding and language /// </summary> /// <param name="fileEncoding">File encoding</param> /// <param name="htmlTextTranslations">Translations dictionary</param> /// <param name="translationsLanguage">Translations language</param> /// <returns></returns> public POCatalog CreateCatalog(Encoding fileEncoding, IOrderedDictionary <string, string> htmlTextTranslations, string translationsLanguage) { var catalog = new POCatalog { // Setting Required Headers Encoding = fileEncoding.HeaderName, Language = translationsLanguage, // Setting Custom Headers Headers = CreateHeaders() }; foreach (var htmlTextTranslation in htmlTextTranslations) { var poKey = new POKey(htmlTextTranslation.Key); var poEntry = new POSingularEntry(poKey) { Translation = htmlTextTranslation.Value }; catalog.Add(poEntry); } return(catalog); }
public void ParseWithStringDecodingOptions() { CheckCatalog(new POStringDecodingOptions { }, Environment.NewLine, Environment.NewLine); CheckCatalog(new POStringDecodingOptions { KeepKeyStringsPlatformIndependent = true }, "\n", Environment.NewLine); CheckCatalog(new POStringDecodingOptions { KeepTranslationStringsPlatformIndependent = true }, Environment.NewLine, "\n"); CheckCatalog(new POStringDecodingOptions { KeepKeyStringsPlatformIndependent = true, KeepTranslationStringsPlatformIndependent = true }, "\n", "\n"); void CheckCatalog(POStringDecodingOptions options, string expectedKeyStringNewLine, string expectedTranslationStringNewLine) { var parserSettings = new POParserSettings { StringDecodingOptions = options }; var parser = new POParser(parserSettings); POParseResult result = parser.Parse(new MemoryStream(Resources.NewLineTestPO)); Assert.True(result.Success); POCatalog catalog = result.Catalog; Assert.Equal(4, catalog.Headers.Count); Assert.Equal("en_US", catalog.Headers["Language"]); Assert.Equal(1, catalog.Count); Assert.Equal( new POKey($"Id of{expectedKeyStringNewLine}a long text", $"Plural id of{expectedKeyStringNewLine}a long text", $"Context id of{expectedKeyStringNewLine}a long text"), catalog[0].Key); IPOEntry entry = catalog[0]; Assert.Equal(2, entry.Count); Assert.Equal($"Singular translation of{expectedTranslationStringNewLine}a long text", entry[0]); Assert.Equal($"Plural translation of{expectedTranslationStringNewLine}a long text", entry[1]); IList <POComment> comments = catalog[0].Comments; Assert.Equal(3, comments?.Count ?? 0); POComment comment = comments[0]; Assert.Equal(POCommentKind.PreviousValue, comment.Kind); Assert.Equal(POIdKind.ContextId, ((POPreviousValueComment)comment).IdKind); Assert.Equal($"Previous context id of{expectedKeyStringNewLine}a long text", ((POPreviousValueComment)comment).Value); comment = comments[1]; Assert.Equal(POCommentKind.PreviousValue, comment.Kind); Assert.Equal(POIdKind.Id, ((POPreviousValueComment)comment).IdKind); Assert.Equal($"Previous id of{expectedKeyStringNewLine}a long text", ((POPreviousValueComment)comment).Value); comment = comments[2]; Assert.Equal(POCommentKind.PreviousValue, comment.Kind); Assert.Equal(POIdKind.PluralId, ((POPreviousValueComment)comment).IdKind); Assert.Equal($"Previous plural id of{expectedKeyStringNewLine}a long text", ((POPreviousValueComment)comment).Value); } }
private static POCatalog BuildCatalog(string filePath, POCatalog templateCatalog) { POCatalog?originalCatalog; if (File.Exists(filePath)) { using (var reader = new StreamReader(filePath)) { var parseResult = new POParser().Parse(reader); if (!parseResult.Success) { var diagnosticMessages = parseResult.Diagnostics .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error); throw new CommandException($"Template file \"{filePath}\" is invalid: {string.Join(Environment.NewLine, diagnosticMessages)}"); } originalCatalog = parseResult.Catalog; } } else { originalCatalog = null; } var catalog = new POCatalog(); foreach (var templateEntry in templateCatalog) { var flags = new HashSet <string>(GetPOEntryFlags(templateEntry)); if (flags.Contains("removed")) { continue; } IEnumerable <string> originalFlags; if (originalCatalog != null && originalCatalog.TryGetValue(templateEntry.Key, out var originalEntry)) { originalFlags = GetPOEntryFlags(originalEntry); } else { (originalFlags, originalEntry) = (Enumerable.Empty <string>(), null); } var isNew = flags.Remove("new"); var hasChanged = flags.Remove("changed"); var isOriginalFuzzy = originalFlags.Contains("fuzzy"); IPOEntry entry = (hasChanged ? templateEntry : (originalEntry ?? templateEntry)) switch { POSingularEntry singularEntry => new POSingularEntry(templateEntry.Key) { Translation = singularEntry.Translation }, POPluralEntry pluralEntry => new POPluralEntry(templateEntry.Key, pluralEntry), _ => throw new InvalidOperationException() }; if (isNew || hasChanged || isOriginalFuzzy) { flags.Add("fuzzy"); entry.Comments = templateEntry.Comments?.Where(comment => !(comment is POFlagsComment)).ToList() ?? new List <POComment>(); entry.Comments.Add(new POFlagsComment { Flags = flags }); } else { entry.Comments = templateEntry.Comments; } catalog.Add(entry); } return(catalog); }
private POCatalog BuildTemplateCatalog(string?filePath, KeyValuePair <string, ExtractResult>[] fileTexts) { POCatalog?originalCatalog; if (File.Exists(filePath)) { using (var reader = new StreamReader(filePath !)) { var parseResult = new POParser().Parse(reader); if (!parseResult.Success) { var diagnosticMessages = parseResult.Diagnostics .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error); throw new CommandException($"Template file \"{filePath}\" is invalid: {string.Join(Environment.NewLine, diagnosticMessages)}"); } originalCatalog = parseResult.Catalog; for (var i = originalCatalog.Count - 1; i >= 0; i--) { var originalEntry = originalCatalog[i]; if (GetPOEntryFlags(originalEntry).Contains("removed")) { originalCatalog.RemoveAt(i); } } } } else { originalCatalog = null; } var groupsById = fileTexts .Where(fileText => fileText.Value.Texts != null) .SelectMany(fileText => fileText.Value.Texts !.Select(text => (text, fileText.Key))) .GroupBy(item => new POKey(item.text.Id, item.text.PluralId, item.text.ContextId)) .OrderBy(item => item.Key, POKeyComparer.Instance); var catalog = new POCatalog(); foreach (var groupById in groupsById) { var key = groupById.Key; foreach (var(text, sourceFilePath) in groupById) { if (!catalog.TryGetValue(key, out var entry)) { var state = "new"; if (originalCatalog != null && originalCatalog.TryGetValue(key, out var originalEntry)) { var hasChanged = originalEntry.Count == 0 || originalEntry[0] != text.Id || (text.PluralId == null ? originalEntry.Count > 1 : originalEntry.Count != 2 || originalEntry[1] != text.PluralId); state = hasChanged ? "changed" : null; } entry = text.PluralId == null ? (IPOEntry) new POSingularEntry(key) { Translation = text.Id } : new POPluralEntry(key) { text.Id, text.PluralId }; entry.Comments = new List <POComment>(); if (state != null) { entry.Comments.Add(new POFlagsComment { Flags = new HashSet <string> { state } }); } if (!NoReferences) { entry.Comments.Add(new POReferenceComment() { References = new List <POSourceReference>() }); } catalog.Add(entry); } if (!NoReferences) { var referenceComment = entry.Comments.OfType <POReferenceComment>().First(); referenceComment.References.Add(new POSourceReference(sourceFilePath, text.LineNumber)); } if (!NoComments && !string.IsNullOrEmpty(text.Comment)) { entry.Comments.Add(new POExtractedComment { Text = text.Comment }); } } } if (originalCatalog != null) { foreach (var originalEntry in originalCatalog) { if (!catalog.Contains(originalEntry.Key)) { var entry = new POSingularEntry(originalEntry.Key) { Translation = "***THIS ENTRY WAS REMOVED. DO NOT TRANSLATE!***" }; entry.Comments = new List <POComment> { new POFlagsComment { Flags = new HashSet <string> { "removed" } } }; catalog.Add(entry); } } } return(catalog); }
public static POCatalog CreateCatalog() { var result = new POCatalog(); result.HeaderComments = new POComment[] { new POTranslatorComment { Text = "header comment" } }; result.Headers = new OrderedDictionary <string, string> { { "Language-Team", "" }, { "PO-Revision-Date", "" }, { "POT-Creation-Date", "2018-06-22 07:01+0200" }, { "Project-Id-Version", "" }, { "Report-Msgid-Bugs-To", "" }, { "MIME-Version", "1.0" }, { "X-Generator", "Poedit 2.0.8" }, { "Last-Translator", "" }, }; result.Encoding = "UTF-8"; result.PluralFormCount = 2; result.PluralFormSelector = "(n != 1)"; result.Language = "en_US"; var key = new POKey("{0} hour to midnight", "{0} hours to midnight", "Home"); IPOEntry entry = new POPluralEntry(key) { "Translation of {0} hour to midnight", "Translation of {0} hours to midnight", }; entry.Comments = new POComment[] { new POTranslatorComment { Text = "some translator comment" }, new POExtractedComment { Text = "some extracted comment" }, new POReferenceComment { References = new POSourceReference[] { new POSourceReference("/Views/Home/Index.cshtml", 8) } }, new POFlagsComment { Flags = new SortedSet <string> { "fuzzy", "csharp-format" } }, new POPreviousValueComment { IdKind = POIdKind.Id, Value = "{0} hour to midnite" }, new POPreviousValueComment { IdKind = POIdKind.PluralId, Value = "{0} hours to midnite" }, }; result.Add(entry); key = new POKey($"Here is an example of how one might continue a very long string{Environment.NewLine}" + $"for the common case the string represents multi-line output.{Environment.NewLine}"); entry = new POSingularEntry(key) { Translation = "Some translation of long text" }; result.Add(entry); return(result); }
public static string GetCultureName(this POCatalog catalogo) => new CultureInfo(catalogo.Language.Replace("_", "-")).Name;
public void Init(IEnumerable <ILocalizationRecord> localizationRecords, IEnumerable <IPluralFormRule> pluralFormRules, bool reLoad = false) { if (TextCatalogs == null || TextCatalogs.Count == 0 || reLoad) { var textCatalogs = new Dictionary <string, POCatalog>(); try { foreach (var culture in localizationRecords.Select(i => i.Culture).Distinct()) { var pluralFormRule = pluralFormRules.SingleOrDefault(i => i.Language == culture); if (pluralFormRule == null) { Logger.LogError($"Missing PluralFormRule for {culture}"); continue; } var catalog = new POCatalog { Encoding = "UTF-8", PluralFormCount = pluralFormRule.Count, PluralFormSelector = pluralFormRule.Selector, Language = culture, Headers = new Dictionary <string, string> { { "X-Generator", "BlazorBoilerplate" }, } }; foreach (var localizationRecord in localizationRecords.Where(i => i.Culture == culture)) { try { if (localizationRecord.PluralTranslations.Count == 0) { catalog.Add(new POSingularEntry(new POKey(localizationRecord.MsgId, contextId: localizationRecord.ContextId)) { Translation = localizationRecord.Translation }); } else { var entry = new POPluralEntry(new POKey(localizationRecord.MsgId, localizationRecord.MsgIdPlural, localizationRecord.ContextId), localizationRecord.PluralTranslations.OrderBy(i => i.Index).Select(i => i.Translation)); catalog.Add(entry); } } catch (Exception ex) { Logger.LogError($"Import localizationRecord {localizationRecord.MsgId}: {ex.GetBaseException().Message}"); } } textCatalogs.Add(culture, catalog); } } catch (Exception ex) { Logger.LogError($"Init: {ex.GetBaseException().StackTrace}"); } TextCatalogs = textCatalogs; } }
public POStringLocalizer(CultureInfo culture, Func <CultureInfo, POCatalog> getCatalogForCulture, ILogger <POStringLocalizer> logger) { _catalog = getCatalogForCulture(culture); _getCatalogForCulture = getCatalogForCulture; _logger = logger; }
private void CheckHeader(POCatalog catalog, bool expectComments, bool expectInfoHeaders, bool expectOrderedHeaders) { if (expectInfoHeaders) { Assert.Equal(12, catalog.Headers.Count); Assert.Equal("8bit", catalog.Headers["Content-Transfer-Encoding"]); Assert.Equal("text/plain; charset=UTF-8", catalog.Headers["Content-Type"]); Assert.Equal("", catalog.Headers["Language-Team"]); Assert.Equal("nplurals=2; plural=(n != 1);", catalog.Headers["Plural-Forms"]); Assert.Equal("", catalog.Headers["PO-Revision-Date"]); Assert.Equal("2018-06-22 07:01+0200", catalog.Headers["POT-Creation-Date"]); Assert.Equal("", catalog.Headers["Project-Id-Version"]); Assert.Equal("", catalog.Headers["Report-Msgid-Bugs-To"]); Assert.Equal("1.0", catalog.Headers["MIME-Version"]); Assert.Equal("Poedit 2.0.8", catalog.Headers["X-Generator"]); Assert.Equal("", catalog.Headers["Last-Translator"]); Assert.Equal("en_US", catalog.Headers["Language"]); } else { Assert.Null(catalog.Headers); } if (expectOrderedHeaders) { #if USE_COMMON Assert.IsAssignableFrom <Karambolo.Common.Collections.IOrderedDictionary <string, string> >(catalog.Headers); Assert.Equal(new[] { "Content-Transfer-Encoding", "Content-Type", "Language", "Language-Team", "Last-Translator", "MIME-Version", "Plural-Forms", "PO-Revision-Date", "POT-Creation-Date", "Project-Id-Version", "Report-Msgid-Bugs-To", "X-Generator" }, catalog.Headers.Keys); #else Assert.True(false, "Compact version doesn't include PreserveHeadersOrder."); #endif } Assert.Equal("UTF-8", catalog.Encoding); Assert.Equal("en_US", catalog.Language); Assert.Equal(2, catalog.PluralFormCount); Assert.Equal("(n != 1)", catalog.PluralFormSelector); #if USE_HIME Assert.Equal(0, catalog.GetPluralFormIndex(1)); Assert.Equal(1, catalog.GetPluralFormIndex(2)); Assert.Equal(1, catalog.GetPluralFormIndex(5)); #else Assert.Equal(0, catalog.GetPluralFormIndex(1)); Assert.Equal(0, catalog.GetPluralFormIndex(2)); Assert.Equal(0, catalog.GetPluralFormIndex(5)); #endif if (expectComments) { Assert.Equal(1, catalog.HeaderComments.Count); IList <POComment> comments = catalog.HeaderComments; Assert.Equal(POCommentKind.Translator, comments[0].Kind); Assert.Equal("header comment", ((POTranslatorComment)comments[0]).Text); } else { Assert.Null(catalog.HeaderComments); } }
public async Task Visit(DataStructure dataStructure) { await Task.CompletedTask; var language = Thread.CurrentThread.CurrentCulture.Name; var projectName = dataStructure.Project.Name; var projectPath = dataStructure.ProjectDirectory; var localizerEntries = dataStructure.LocalizerEntries; var POFilePath = Path.Combine(projectPath, "Localization", language + ".po"); POCatalog catalog = null; if (File.Exists(POFilePath)) { using var sr = new StreamReader(POFilePath, Encoding.UTF8); var parser = new POParser(POParserSettings.Default); var result = parser.Parse(sr); if (result.Success) { catalog = result.Catalog; foreach (var r in catalog) { r.Comments.Clear(); } } else { var diagnostics = result.Diagnostics; // examine diagnostics, display an error, etc... foreach (var diagnostic in diagnostics) { if (diagnostic.Severity.Equals(Karambolo.PO.DiagnosticSeverity.Error)) { Console.WriteLine($"Error has occurred while Parse the PO file: {POFilePath}"); } } } } if (catalog == null) { catalog = new POCatalog { Encoding = Encoding.UTF8.BodyName, PluralFormCount = 1, PluralFormSelector = "0", Language = language }; var assembly = typeof(IVisitor).Assembly; catalog.Headers = new Dictionary <string, string> { { "PO-Revision-Date", DateTime.UtcNow.ToString() }, { "Project-Id-Version", projectName }, { "X-Crowdin-Generator", $"Generated by {assembly.GetName().Name} {assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion}" }, }; } HashSet <POKey> sets = new HashSet <POKey>(); foreach (var entry in localizerEntries) { var key = new POKey(entry.Id, null, entry.ContextId); sets.Add(key); if (catalog.TryGetValue(key, out var POEntry)) { if (!POEntry.Comments.OfType <POExtractedComment>().Any(c => c.Text.Equals(entry.SourceCode))) { POEntry.Comments.Add(new POExtractedComment { Text = entry.SourceCode }); } var referenceComment = POEntry.Comments.OfType <POReferenceComment>().FirstOrDefault(); if (referenceComment == null) { POEntry.Comments.Add(new POReferenceComment { References = new List <POSourceReference>() { POSourceReference.Parse(entry.SourceReference) } }); } else { var sourceReference = POSourceReference.Parse(entry.SourceReference); if (!referenceComment.References.Any(r => r.FilePath.Equals(sourceReference.FilePath) && r.Line.Equals(sourceReference.Line))) { referenceComment.References.Add(sourceReference); } } } else { POEntry = new POSingularEntry(key) { Comments = new List <POComment>() { new POReferenceComment { References = new List <POSourceReference>() { POSourceReference.Parse(entry.SourceReference) } }, new POExtractedComment { Text = entry.SourceCode }, } }; catalog.Add(POEntry); } } var keys = catalog.Keys.ToList(); keys.Where(k => !sets.Contains(k)).ToList().ForEach(k => catalog.Remove(k)); if (catalog.Headers.ContainsKey("PO-Revision-Date")) { catalog.Headers["PO-Revision-Date"] = DateTime.UtcNow.ToString(); } var generator = new POGenerator(POGeneratorSettings.Default); using var sw = new StreamWriter(POFilePath, false, Encoding.UTF8); generator.Generate(sw, catalog); }
public static TranslationCatalogData ToData(this POCatalog catalog) => new TranslationCatalogData