Example #1
0
 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;
 }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
 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);
        }
Example #8
0
        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
            }
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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);
            }
        }
Example #13
0
        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);
        }
Example #14
0
        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"));
        }
Example #15
0
        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);
                    }
                }
Example #16
0
        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);
                }
        }
Example #17
0
        /// <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);
        }
Example #18
0
        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('_', '-')));
                }
            }
        }
Example #19
0
        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);
        }
Example #20
0
        /// <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);
        }
Example #21
0
        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);
            }
        }
Example #22
0
        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);
        }
Example #23
0
        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);
        }
Example #24
0
        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);
        }
Example #25
0
 public static string GetCultureName(this POCatalog catalogo) => new CultureInfo(catalogo.Language.Replace("_", "-")).Name;
Example #26
0
        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;
            }
        }
Example #27
0
 public POStringLocalizer(CultureInfo culture, Func <CultureInfo, POCatalog> getCatalogForCulture, ILogger <POStringLocalizer> logger)
 {
     _catalog = getCatalogForCulture(culture);
     _getCatalogForCulture = getCatalogForCulture;
     _logger = logger;
 }
Example #28
0
        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);
            }
        }
Example #29
0
        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);
        }
Example #30
0
 public static TranslationCatalogData ToData(this POCatalog catalog) => new TranslationCatalogData