コード例 #1
0
        private void ExtractComments(POKey key, POSingularEntry entry)
        {
            foreach (var comment in entry.Comments)
            {
                if (!(comment is POTranslatorComment translatorComment))
                {
                    continue;
                }

                var commentText = translatorComment.Text;

                if (string.IsNullOrEmpty(commentText))
                {
                    continue;
                }

                commentText = commentText.Replace(PartialMatchComment, "").Trim(new char[] { ';', ' ' });

                if (string.IsNullOrEmpty(commentText))
                {
                    continue;
                }

                if (Comments.ContainsKey(key.Id))
                {
                    Debug.WriteLine($"Duplicate translator comment: '{commentText}'");
                    continue;
                }

                Comments[key.Id] = commentText;
            }
        }
コード例 #2
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);
        }
コード例 #3
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);
            }
        }
コード例 #4
0
ファイル: POEntry.cs プロジェクト: gitter-badger/po
        public POPluralEntry(POKey key)
        {
            if (!key.IsValid)
            {
                throw new ArgumentException(null, nameof(key));
            }

            Key = key;
        }
コード例 #5
0
ファイル: POEntry.cs プロジェクト: GioviQ/po
        private POPluralEntry(POKey key, IList <string> translations)
            : base(translations)
        {
            if (!key.IsValid)
            {
                throw new ArgumentException(null, nameof(key));
            }

            Key = key;
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        public static string FormatKey(POKey key)
        {
            var result = string.Concat("'", key.Id, "'");

            if (key.PluralId != null)
            {
                result = string.Concat(result, "-'", key.PluralId, "'");
            }
            if (key.ContextId != null)
            {
                result = string.Concat(result, "@'", key.ContextId, "'");
            }

            return(result);
        }
コード例 #8
0
        protected override bool TryGetTranslation(string name, Plural plural, TextContext context, out string value)
        {
            var key = new POKey(name, plural.Id, context.Id);

            if (!TryGetTranslationCore(key, plural.Count, out string translation))
            {
                Logger.LogTrace("No translation for key {0}.", POStringLocalizer.FormatKey(key));

                base.TryGetTranslation(name, plural, context, out value);
                return(false);
            }

            value = translation;
            return(true);
        }
コード例 #9
0
        bool TryGetTranslation(string name, Plural plural, TextContext context, out string value)
        {
            var key = new POKey(name, plural.Id, context.Id);

            if (!TryGetTranslation(key, plural.Count, out string translation))
            {
                _logger.LogTrace("No translation for key {KEY}.", POStringLocalizer.FormatKey(key));

                TryGetTranslationFallback(name, plural, context, out value);
                return(false);
            }

            value = translation;
            return(true);
        }
コード例 #10
0
        bool TryGetTranslation(POKey key, int pluralCount, out string value)
        {
            if (_catalog != null)
            {
                var translation = _catalog.GetTranslation(key, pluralCount);
                if (translation != null)
                {
                    value = translation;
                    return(true);
                }
            }

            value = null;
            return(false);
        }
コード例 #11
0
        public bool TryGetTranslation(string name, Plural plural, TextContext context, out string?searchedLocation, [MaybeNullWhen(false)] out string value)
        {
            var catalog = GetCatalog();

            if (catalog != null)
            {
                var key = new POKey(name, plural.Id, context.Id);
                value = plural.Id == null?catalog.GetTranslation(key) : catalog.GetTranslation(key, plural.Count);

                if (value != null)
                {
                    searchedLocation = _location;
                    return(true);
                }
            }

            searchedLocation = _location;
            value            = default;
            return(false);
        }
コード例 #12
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);
        }
コード例 #13
0
        public static void LoadDataPOFile()
        {
            POFileData.Clear();

            var pathPoFile = GetPathFilePo(DefaultLanguageValue);

            if (string.IsNullOrEmpty(pathPoFile) || !File.Exists(pathPoFile))
            {
                return;
            }

            using (var reader = new StreamReader(pathPoFile, Encoding.UTF8))
            {
                var parser = new POParser();
                var result = parser.Parse(reader);

                if (!result.Success)
                {
                    return;
                }

                var catalog = result.Catalog;
                //var languageName = catalog.Language.Replace('_', '-').Trim();
                var languageName = DefaultLanguageValue.Replace('_', '-');
                languageName = languageName.Replace(".po", "").Trim();
                CultureInfo ci = new CultureInfo(languageName);
                CultureInfo.DefaultThreadCurrentCulture = ci;

                foreach (var item in catalog)
                {
                    var keyLangue   = item.Key.Id;
                    var key         = new POKey(keyLangue);
                    var translation = catalog.GetTranslation(key);

                    POFileData.Add(keyLangue, translation);
                }
            }
        }
コード例 #14
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);
        }
コード例 #15
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);
        }
コード例 #16
0
ファイル: POGeneratorTest.cs プロジェクト: dmc31a42/po
        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);
        }
コード例 #17
0
        public IEnumerable <string> SaveTo(string filename, DateTime versionDate, List <ExtractedText> entries)
        {
            var translationCatalog = CreateCatalog();
            var sanityChecker      = new ExtractedTextSanityChecker();

            entries.Sort((x, y) =>
            {
                if (x.Source == y.Source)
                {
                    return(x.SourceLine.CompareTo(y.SourceLine));
                }

                return(new NaturalStringComparer().Compare(x.Source, y.Source));
            });

            var warnings = new List <string>();

            foreach (var entry in entries)
            {
                // There are a lot of this string in various unrelated parts of the structure, seems to be a generic
                // error string. We don't want it anywhere but the error string table.
                if (entry.Japanese == "2-エラーが発生しました。" && !entry.Source.StartsWith("ServerErrString"))
                {
                    continue;
                }

                var key = new POKey(entry.Japanese);
                if (translationCatalog.Contains(key))
                {
                    continue;
                }

                // Since PO catalogs can't contain duplicate entries any after this will be skipped. We pull the Korean
                // text from the duplicate entries if they have it and we don't.
                //
                // This is needed for the PCStory PO file to contain both. The PCStory table only contains Japanese
                // while the PCStory_Client contains both (but doesn't have contextual key names so we prefer PCStory).
                // For example, for a string in PCStory_Client the path is PCStory_Client[1][0].DgStartTriggerString1,
                // in PCStory the path is PCStory[Story_3P_ConstantiaS2_1_3P_ConstantiaS2_1].DgStartTriggerString1.
                if (string.IsNullOrEmpty(entry.Korean))
                {
                    var otherEntryWithKorean = entries.Where(e =>
                    {
                        return(e != entry &&
                               e.Japanese.Equals(entry.Japanese, StringComparison.Ordinal) &&
                               !string.IsNullOrEmpty(e.Korean));
                    }).FirstOrDefault();

                    if (otherEntryWithKorean != null)
                    {
                        entry.Korean = otherEntryWithKorean.Korean;
                    }
                }

                warnings.AddRange(sanityChecker.GetWarnings(entry));

                AddToCatalog(translationCatalog, entry);
            }

            WriteCatalog(translationCatalog, filename, versionDate);

            return(warnings);
        }
コード例 #18
0
ファイル: POEntry.cs プロジェクト: GioviQ/po
 public POPluralEntry(POKey key, IEnumerable <string> translations)
     : this(key, (translations ?? throw new ArgumentNullException(nameof(translations))).ToList())
コード例 #19
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);
        }
コード例 #20
0
ファイル: POEntry.cs プロジェクト: GioviQ/po
 public POPluralEntry(POKey key)
     : this(key, new List <string>())
 {
 }