Adds support to LocalizationStreamParser for po entrys spanning multiple lines (#7752)

This commit is contained in:
Andrew Cartwright 2017-07-06 20:13:05 +01:00 committed by Sébastien Ros
parent 93f8129cfa
commit eff20785aa

View File

@ -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<char, char> _escapeTranslations = new Dictionary<char, char> {
{ 'n', '\n' },
{ 'r', '\r' },
@ -22,51 +27,81 @@ namespace Orchard.Localization.Services {
public void ParseLocalizationStream(string text, IDictionary<string, string> translations, bool merge) {
var reader = new StringReader(text);
string poLine;
var scopes = new List<string>();
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<string>();
id = string.Empty;
scopes = new List<string>();
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()));
}
}
}
}