Exemple #1
0
        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);
        }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        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;
            }
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        /// <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);
            }
        }
Exemple #7
0
        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 + "'");
            }
        }
Exemple #8
0
 static string GetKey(PoEntry entry)
 {
     return(GetKey(entry.Original, entry.Context));
 }