diff --git a/src/Orchard/Localization/Services/LocalizationStreamParser.cs b/src/Orchard/Localization/Services/LocalizationStreamParser.cs index ad824bc58..e4a8e7e4d 100644 --- a/src/Orchard/Localization/Services/LocalizationStreamParser.cs +++ b/src/Orchard/Localization/Services/LocalizationStreamParser.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -8,6 +8,11 @@ namespace Orchard.Localization.Services { public class LocalizationStreamParser : ILocalizationStreamParser { + private const string HashtagScope = "#:"; + private const string MsgctxtScope = "msgctxt"; + private const string MsgidScope = "msgid"; + private const string MsgstrScope = "msgstr"; + private static readonly Dictionary _escapeTranslations = new Dictionary { { 'n', '\n' }, { 'r', '\r' }, @@ -22,51 +27,81 @@ namespace Orchard.Localization.Services { public void ParseLocalizationStream(string text, IDictionary translations, bool merge) { var reader = new StringReader(text); - string poLine; var scopes = new List(); var id = string.Empty; + var activeScope = string.Empty; - while ((poLine = reader.ReadLine()) != null) { - if (poLine.StartsWith("#:")) { - scopes.Add(ParseScope(poLine)); - continue; + string currentPoLine = reader.ReadLine() ?? ""; + + do + { + if (currentPoLine.StartsWith(HashtagScope)) + { + currentPoLine = Parse(HashtagScope, currentPoLine); + activeScope = HashtagScope; + } + else if (currentPoLine.StartsWith(MsgctxtScope)) + { + currentPoLine = Parse(MsgctxtScope, currentPoLine); + activeScope = MsgctxtScope; + } + else if (currentPoLine.StartsWith(MsgidScope)) + { + currentPoLine = Parse(MsgidScope, currentPoLine); + activeScope = MsgidScope; + } + else if (currentPoLine.StartsWith(MsgstrScope)) + { + currentPoLine = Parse(MsgstrScope, currentPoLine); + activeScope = MsgstrScope; } - if (poLine.StartsWith("msgctxt")) { - scopes.Add(ParseContext(poLine)); - continue; + string nextPoLine = reader.ReadLine() ?? ""; + + while (nextPoLine != null && (!nextPoLine.StartsWith("#") && !nextPoLine.StartsWith(MsgctxtScope) && + !nextPoLine.StartsWith(MsgidScope) && !nextPoLine.StartsWith(MsgstrScope))) + { + currentPoLine = string.Concat(currentPoLine, TrimQuote(nextPoLine)); + nextPoLine = reader.ReadLine(); } - if (poLine.StartsWith("msgid")) { - id = ParseId(poLine); - continue; - } + switch (activeScope) + { + case HashtagScope: + case MsgctxtScope: + scopes.Add(currentPoLine); + break; - if (poLine.StartsWith("msgstr")) { - var translation = ParseTranslation(poLine); - // ignore incomplete localizations (empty msgid or msgstr) - if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(translation)) { - if(scopes.Count == 0) { - scopes.Add(string.Empty); - } - foreach (var scope in scopes) { - var scopedKey = (scope + "|" + id).ToLowerInvariant(); - if (!translations.ContainsKey(scopedKey)) { - translations.Add(scopedKey, translation); + case MsgidScope: + id = currentPoLine; + break; + + case MsgstrScope: + if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(currentPoLine)) { + if (scopes.Count == 0) { + scopes.Add(string.Empty); } - else { - if (merge) { - translations[scopedKey] = translation; + foreach (var scope in scopes) { + var scopedKey = (scope + "|" + id).ToLowerInvariant(); + if (!translations.ContainsKey(scopedKey)) { + translations.Add(scopedKey, currentPoLine); + } + else { + if (merge) { + translations[scopedKey] = currentPoLine; + } } } } - } - id = string.Empty; - scopes = new List(); + id = string.Empty; + scopes = new List(); + break; } - } + currentPoLine = nextPoLine; + activeScope = string.Empty; + } while (currentPoLine != null); } private static string Unescape(string str) { @@ -117,20 +152,9 @@ namespace Orchard.Localization.Services { return str; } - private string ParseTranslation(string poLine) { - return Unescape(TrimQuote(poLine.Substring(6).Trim())); - } - - private string ParseId(string poLine) { - return Unescape(TrimQuote(poLine.Substring(5).Trim())); - } - - private string ParseScope(string poLine) { - return Unescape(TrimQuote(poLine.Substring(2).Trim())); - } - - private string ParseContext(string poLine) { - return Unescape(TrimQuote(poLine.Substring(7).Trim())); + private string Parse(string str, string poLine) + { + return Unescape(TrimQuote(poLine.Substring(str.Length).Trim())); } } -} \ No newline at end of file +}