예제 #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
        private void DisplayCatalogEntry()
        {
            if (_currentEntryIndex == null || _currentEntryIndex >= _catalog.Count || _currentEntryIndex < 0)
            {
                //err
                return;
            }
            _currentEntry           = (POSingularEntry)_catalog[_currentEntryIndex];
            idTextBox.Text          = _currentEntry.Key.Id;
            translationTextBox.Text = _currentEntry.Translation;
            entryCountLabel.Text    = (_currentEntryIndex + 1) + COUNT_SEPARATOR + _catalog.Count;
            var commentsTextBuilder = new StringBuilder();

            foreach (var comment in _currentEntry.Comments)
            {
                if (comment.Kind == POCommentKind.Extracted)
                {
                    commentsTextBuilder.AppendLine(((POExtractedComment)comment).Text);
                }
                else if (comment.Kind == POCommentKind.Reference)
                {
                    commentsTextBuilder.AppendLine(GetReferenceCommentText((POReferenceComment)comment));
                }
            }
            commentsTextBox.Text = commentsTextBuilder.ToString();
        }
예제 #3
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);
        }
예제 #4
0
        private POSingularEntry TransformSingularEntry(POSingularEntry singular)
        {
            string translation = Transform(singular.Translation);

            return(new POSingularEntry(singular.Key)
            {
                Translation = translation,
                Comments = singular.Comments,
            });
        }
예제 #5
0
        public static POCatalog GetDialogueCatalog(this DialogueDatabase db)
        {
            var actors = GetActors(db);

            var catalog = InitCatalog();

            foreach (var conversation in db.conversations)
            {
                foreach (var dialogue in conversation.dialogueEntries)
                {
                    foreach (var field in dialogue.fields)
                    {
                        if (string.IsNullOrWhiteSpace(field.value))
                        {
                            continue;
                        }
                        if (!DialogueTranslatableFields.Contains(field.title))
                        {
                            continue;
                        }

                        string key    = $"{field.title}/{Field.LookupValue(dialogue.fields, "Articy Id")}";
                        string source = field.value;

                        var entry = new POSingularEntry(new POKey(source, contextId: key))
                        {
                            Comments = new List <POComment>()
                        };

                        entry.Comments.Add(new POTranslatorComment {
                            Text = $"Title = {conversation.Title}"
                        });
                        entry.Comments.Add(new POTranslatorComment {
                            Text = $"Description = {conversation.Description.Replace("\n", "\\n")}"
                        });
                        if (actors.TryGetValue(dialogue.ActorID, out Actor actor))
                        {
                            entry.Comments.Add(new POTranslatorComment {
                                Text = $"Actor = {actor.Name}"
                            });
                        }
                        if (actors.TryGetValue(dialogue.ConversantID, out Actor conversant))
                        {
                            entry.Comments.Add(new POTranslatorComment {
                                Text = $"Conversant = {conversant.Name}"
                            });
                        }

                        catalog.Add(entry);
                    }
                }
            }

            return(catalog);
        }
예제 #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
        private static bool WasPartial(POSingularEntry entry)
        {
            foreach (var comment in entry.Comments)
            {
                if (!(comment is POTranslatorComment translatorComment))
                {
                    continue;
                }

                if (translatorComment.Text.Contains(PartialMatchComment, StringComparison.OrdinalIgnoreCase))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #8
0
        public static POCatalog LanguageSourceToCatalog(I2.Loc.LanguageSourceAsset languageSource, int languageIndex)
        {
            var catalog = InitCatalog();

            foreach (var term in languageSource.mSource.mTerms)
            {
                string key    = term.Term;
                string source = term.Languages[languageIndex];

                if (string.IsNullOrWhiteSpace(source) || source == "\"")
                {
                    continue;
                }

                var entry = new POSingularEntry(new POKey(source, contextId: key));
                catalog.Add(entry);
            }

            return(catalog);
        }
예제 #9
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);
        }
예제 #10
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);
        }
예제 #11
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);
        }
예제 #12
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);
        }
예제 #13
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);
        }
예제 #14
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);
        }
예제 #15
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);
        }