mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-04-05 21:01:35 +08:00
Adds support to LocalizationStreamParser for po entrys spanning multiple lines (#7752)
This commit is contained in:
parent
93f8129cfa
commit
eff20785aa
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -8,6 +8,11 @@ namespace Orchard.Localization.Services {
|
|||||||
|
|
||||||
public class LocalizationStreamParser : ILocalizationStreamParser {
|
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> {
|
private static readonly Dictionary<char, char> _escapeTranslations = new Dictionary<char, char> {
|
||||||
{ 'n', '\n' },
|
{ 'n', '\n' },
|
||||||
{ 'r', '\r' },
|
{ 'r', '\r' },
|
||||||
@ -22,51 +27,81 @@ namespace Orchard.Localization.Services {
|
|||||||
|
|
||||||
public void ParseLocalizationStream(string text, IDictionary<string, string> translations, bool merge) {
|
public void ParseLocalizationStream(string text, IDictionary<string, string> translations, bool merge) {
|
||||||
var reader = new StringReader(text);
|
var reader = new StringReader(text);
|
||||||
string poLine;
|
|
||||||
var scopes = new List<string>();
|
var scopes = new List<string>();
|
||||||
var id = string.Empty;
|
var id = string.Empty;
|
||||||
|
var activeScope = string.Empty;
|
||||||
|
|
||||||
while ((poLine = reader.ReadLine()) != null) {
|
string currentPoLine = reader.ReadLine() ?? "";
|
||||||
if (poLine.StartsWith("#:")) {
|
|
||||||
scopes.Add(ParseScope(poLine));
|
do
|
||||||
continue;
|
{
|
||||||
|
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")) {
|
string nextPoLine = reader.ReadLine() ?? "";
|
||||||
scopes.Add(ParseContext(poLine));
|
|
||||||
continue;
|
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")) {
|
switch (activeScope)
|
||||||
id = ParseId(poLine);
|
{
|
||||||
continue;
|
case HashtagScope:
|
||||||
}
|
case MsgctxtScope:
|
||||||
|
scopes.Add(currentPoLine);
|
||||||
|
break;
|
||||||
|
|
||||||
if (poLine.StartsWith("msgstr")) {
|
case MsgidScope:
|
||||||
var translation = ParseTranslation(poLine);
|
id = currentPoLine;
|
||||||
// ignore incomplete localizations (empty msgid or msgstr)
|
break;
|
||||||
if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(translation)) {
|
|
||||||
if(scopes.Count == 0) {
|
case MsgstrScope:
|
||||||
scopes.Add(string.Empty);
|
if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(currentPoLine)) {
|
||||||
}
|
if (scopes.Count == 0) {
|
||||||
foreach (var scope in scopes) {
|
scopes.Add(string.Empty);
|
||||||
var scopedKey = (scope + "|" + id).ToLowerInvariant();
|
|
||||||
if (!translations.ContainsKey(scopedKey)) {
|
|
||||||
translations.Add(scopedKey, translation);
|
|
||||||
}
|
}
|
||||||
else {
|
foreach (var scope in scopes) {
|
||||||
if (merge) {
|
var scopedKey = (scope + "|" + id).ToLowerInvariant();
|
||||||
translations[scopedKey] = translation;
|
if (!translations.ContainsKey(scopedKey)) {
|
||||||
|
translations.Add(scopedKey, currentPoLine);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (merge) {
|
||||||
|
translations[scopedKey] = currentPoLine;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
id = string.Empty;
|
id = string.Empty;
|
||||||
scopes = new List<string>();
|
scopes = new List<string>();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
currentPoLine = nextPoLine;
|
||||||
|
activeScope = string.Empty;
|
||||||
|
} while (currentPoLine != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string Unescape(string str) {
|
private static string Unescape(string str) {
|
||||||
@ -117,20 +152,9 @@ namespace Orchard.Localization.Services {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ParseTranslation(string poLine) {
|
private string Parse(string str, string poLine)
|
||||||
return Unescape(TrimQuote(poLine.Substring(6).Trim()));
|
{
|
||||||
}
|
return Unescape(TrimQuote(poLine.Substring(str.Length).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()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user