private POPluralEntry TransformPluralEntry(POPluralEntry plural) { var entry = new POPluralEntry(plural.Key) { Comments = plural.Comments, }; foreach (string source in plural) { entry.Add(Transform(source)); } return(entry); }
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); }
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); }
private bool TryReadEntry(bool allowEmptyId, out IPOEntry result) { if (_line == null) { result = null; return(false); } var entryLocation = new TextLocation(_lineIndex, _columnIndex); List <POComment> comments = _commentBuffer != null?ParseComments() : null; Dictionary <int, string> translations = null; string id = null, pluralId = null, contextId = null; IPOEntry entry = null; EntryTokens expectedTokens = EntryTokens.Id | EntryTokens.PluralId | EntryTokens.ContextId; do { EntryTokens token = DetectEntryToken(out int tokenLength) & expectedTokens; if (token == EntryTokens.None) { if (!(expectedTokens == EntryTokens.Translation && entry is POPluralEntry)) { AddError(DiagnosticCodes.UnexpectedToken, new TextLocation(_lineIndex, _columnIndex)); result = null; return(false); } else { break; } } _columnIndex += tokenLength; switch (token) { case EntryTokens.Id: _columnIndex = FindNextTokenInLine(requireWhiteSpace: true); if (_columnIndex < 0 || !TryReadString(out id)) { result = null; return(false); } expectedTokens &= ~EntryTokens.Id; expectedTokens |= EntryTokens.Translation; break; case EntryTokens.PluralId: _columnIndex = FindNextTokenInLine(requireWhiteSpace: true); if (_columnIndex < 0 || !TryReadString(out pluralId)) { result = null; return(false); } expectedTokens &= ~EntryTokens.PluralId; break; case EntryTokens.ContextId: _columnIndex = FindNextTokenInLine(requireWhiteSpace: true); if (_columnIndex < 0 || !TryReadString(out contextId)) { result = null; return(false); } expectedTokens &= ~EntryTokens.ContextId; break; case EntryTokens.Translation: var originalColumnIndex = _columnIndex; TryReadPluralIndex(out int?pluralIndex); _columnIndex = FindNextTokenInLine(requireWhiteSpace: true); if (_columnIndex < 0 || !TryReadString(out string value)) { result = null; return(false); } if (!allowEmptyId && entry == null && id == string.Empty) { AddError(Resources.InvalidEntryKey, entryLocation); result = null; return(false); } // plural if (pluralId != null) { if (pluralIndex != null) { if (pluralIndex < 0 || pluralIndex >= _catalog.PluralFormCount) { AddWarning(DiagnosticCodes.InvalidPluralIndex, new TextLocation(_lineIndex, originalColumnIndex)); break; } } else { AddWarning(DiagnosticCodes.MissingPluralIndex, new TextLocation(_lineIndex, originalColumnIndex)); pluralIndex = 0; } if (entry == null) { entry = new POPluralEntry(new POKey(id, pluralId, contextId)) { Comments = comments, }; translations = new Dictionary <int, string>(); } if (translations.ContainsKey(pluralIndex.Value)) { AddWarning(DiagnosticCodes.DuplicatePluralForm, entryLocation, pluralIndex.Value); } translations[pluralIndex.Value] = value; expectedTokens = EntryTokens.Translation; } // singular else { if (pluralIndex != null) { if (pluralIndex != 0) { AddError(DiagnosticCodes.InvalidPluralIndex, new TextLocation(_lineIndex, originalColumnIndex)); break; } else { AddWarning(DiagnosticCodes.UnnecessaryPluralIndex, new TextLocation(_lineIndex, originalColumnIndex)); } } entry = new POSingularEntry(new POKey(id, null, contextId)) { Comments = comments, Translation = value }; expectedTokens = EntryTokens.None; } break; } SeekNextToken(); }while (_line != null && expectedTokens != EntryTokens.None); if (entry is POPluralEntry pluralEntry) { var n = _catalog.PluralFormCount; for (var i = 0; i < n; i++) { if (translations.TryGetValue(i, out string value)) { pluralEntry.Add(value); } else { pluralEntry.Add(null); AddWarning(DiagnosticCodes.MissingPluralForm, entryLocation, i); } } } if (entry == null) { AddError(DiagnosticCodes.IncompleteEntry, entryLocation); result = null; return(false); } result = entry; return(true); }
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; } }