static PoEntry ReadEntry(TextReader reader) { // Skip all the blank lines before the block of text string line = string.Empty; while (reader.PeekLine()?.Trim().Length == 0) { reader.ReadLine(); } // If nothing to read, EOF if (reader.Stream.EndOfStream) { return(null); } PoEntry entry = new PoEntry(); while (!reader.Stream.EndOfStream) { // Get the next line line = reader.ReadLine(); // If it's blank, then this block finished if (string.IsNullOrWhiteSpace(line)) { break; } ParseLine(reader, entry, line); } return(entry); }
/// <summary> /// Convert the specified Binary stream into a PO object. /// </summary> /// <returns>The converted PO object.</returns> /// <param name="source">Source binary stream.</param> public Po Convert(IBinary source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } TextReader reader = new TextReader(source.Stream); Po po = new Po(); // Read the header if any PoEntry entry = ReadEntry(reader); if (entry == null) { return(po); } if (entry.Original.Length == 0) { po.Header = Entry2Header(entry); } else { po.Add(entry); } // Read other entries while ((entry = ReadEntry(reader)) != null) { po.Add(entry); } return(po); }
static void MergeEntry(PoEntry current, PoEntry newEntry) { if (current.Translated != newEntry.Translated) { throw new InvalidOperationException( "Tried to merge Po entries with same original text but " + "different translations."); } if (newEntry.Reference != null) { current.Reference += "," + newEntry.Reference; } }
static PoHeader Entry2Header(PoEntry entry) { PoHeader header = new PoHeader(); var option = StringSplitOptions.RemoveEmptyEntries; foreach (string line in entry.Translated.Split(new[] { '\n' }, option)) { var fields = line.Split(new[] { ": " }, 2, StringSplitOptions.None); if (fields.Length != 2) { throw new FormatException("Invalid format line: " + line); } ParseHeaderLine(header, fields[0], fields[1]); } return(header); }
static void WriteEntry(PoEntry entry, TextWriter writer) { WriteIfNotEmpty(writer, "# {0}", entry.TranslatorComment); WriteIfNotEmpty(writer, "#. {0}", entry.ExtractedComments); WriteIfNotEmpty(writer, "#: {0}", entry.Reference); WriteIfNotEmpty(writer, "#, {0}", entry.Flags); WriteIfNotEmpty(writer, "#| msgctxt {0}", entry.PreviousContext); WriteIfNotEmpty(writer, "#| msgid {0}", entry.PreviousOriginal); if (!string.IsNullOrEmpty(entry.Context)) { writer.Write("msgctxt "); WriteWrappedString(writer, entry.Context); } writer.Write("msgid "); WriteWrappedString(writer, entry.Original); writer.Write("msgstr "); WriteWrappedString(writer, entry.Translated); }
/// <summary> /// Add the specified entry. /// </summary> /// <param name="item">Entry to add. The ID must be unique.</param> public void Add(PoEntry item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (string.IsNullOrEmpty(item.Original)) { throw new FormatException(nameof(item.Original) + " is empty"); } string key = GetKey(item); if (searchEntries.ContainsKey(key)) { MergeEntry(searchEntries[key], item); } else { searchEntries[key] = item; entries.Add(item); } }
static void ParseLine(TextReader reader, PoEntry entry, string line) { string[] fields = line.Split(new[] { ' ' }, 2); if (fields.Length != 2) { throw new FormatException("Invalid line format: " + line); } switch (fields[0]) { case "#": entry.TranslatorComment = ReadMultiLineComment( reader, fields[1].TrimStart(), "# "); break; case "#.": entry.ExtractedComments = ReadMultiLineComment( reader, fields[1], "#."); break; case "#:": entry.Reference = fields[1]; break; case "#,": entry.Flags = fields[1]; break; case "#|": string[] subfields = fields[1].Split(new[] { ' ' }, 2); if (subfields[0] == "msgctxt") { entry.PreviousContext = subfields[1]; } else if (subfields[0] == "msgid") { entry.PreviousOriginal = subfields[1]; } else { throw new FormatException("Unknown previous field: " + line); } break; case "msgctxt": entry.Context = ReadMultiLineContent(reader, fields[1]); break; case "msgid": entry.Original = ReadMultiLineContent(reader, fields[1]); break; case "msgstr": entry.Translated = ReadMultiLineContent(reader, fields[1]); break; default: throw new FormatException("Unknown line '" + line + "'"); } }
static string GetKey(PoEntry entry) { return(GetKey(entry.Original, entry.Context)); }