Add parser for gettext po files.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.6</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Claunia.Localization.Core\Claunia.Localization.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
287
Claunia.Localization.Parsers/GetText.cs
Normal file
287
Claunia.Localization.Parsers/GetText.cs
Normal file
@@ -0,0 +1,287 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Claunia.Localization.Core;
|
||||
|
||||
namespace Claunia.Localization.Parsers
|
||||
{
|
||||
public static class GetText
|
||||
{
|
||||
public static Core.Localization Parse(string catalog)
|
||||
{
|
||||
using(StringReader sr = new StringReader(catalog)) return Parse(sr);
|
||||
}
|
||||
|
||||
public static Core.Localization Parse(string path, Encoding encoding)
|
||||
{
|
||||
using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
using(StreamReader sr = new StreamReader(fs, encoding)) return Parse(sr);
|
||||
}
|
||||
}
|
||||
|
||||
public static Core.Localization Parse(Stream catalog)
|
||||
{
|
||||
using(StreamReader sr = new StreamReader(catalog)) return Parse(sr);
|
||||
}
|
||||
|
||||
public static Core.Localization Parse(TextReader catalog)
|
||||
{
|
||||
Core.Localization localization = new Core.Localization();
|
||||
|
||||
string line = "";
|
||||
string currentMsgId = "";
|
||||
string currentMsgString = "";
|
||||
Translator currentTranslator = null;
|
||||
string currentLocale = null;
|
||||
bool firstEmptyMessageId = true;
|
||||
string currentComment = "";
|
||||
string extractedComment = "";
|
||||
string currentReference = "";
|
||||
string currentContext = "";
|
||||
var currentLanguage = Language.None;
|
||||
|
||||
while(line != null)
|
||||
{
|
||||
line = catalog.ReadLine();
|
||||
|
||||
if(line is null) break;
|
||||
|
||||
if(line == string.Empty)
|
||||
{
|
||||
if(!firstEmptyMessageId)
|
||||
{
|
||||
var message = localization.NewMessage();
|
||||
|
||||
message.Comments = extractedComment;
|
||||
message.Context = currentContext;
|
||||
message.Reference = currentReference;
|
||||
message.Source.Singular = currentMsgId;
|
||||
message.Id = currentMsgId;
|
||||
var localizedString = message.NewLocalizedString();
|
||||
|
||||
localizedString.Comments = currentComment;
|
||||
localizedString.Locale = currentLocale;
|
||||
localizedString.Singular = currentMsgString;
|
||||
localizedString.Translator = currentTranslator?.Id;
|
||||
}
|
||||
|
||||
firstEmptyMessageId = false;
|
||||
currentMsgId = "";
|
||||
currentMsgString = "";
|
||||
currentComment = "";
|
||||
extractedComment = "";
|
||||
currentReference = "";
|
||||
currentContext = "";
|
||||
continue; // TODO
|
||||
}
|
||||
|
||||
if(line[0] == '#')
|
||||
{
|
||||
if(line.Length == 1)
|
||||
{
|
||||
if(!firstEmptyMessageId)
|
||||
currentComment += "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(line[1])
|
||||
{
|
||||
case ' ':
|
||||
if(firstEmptyMessageId) break;
|
||||
|
||||
currentComment += line.Substring(2) + "\n";
|
||||
continue;
|
||||
case '.':
|
||||
extractedComment += line.Substring(2) + "\n";
|
||||
continue;
|
||||
case ':':
|
||||
currentReference += line.Substring(2) + "\n";
|
||||
continue;
|
||||
case ',':
|
||||
var flags = line.Substring(2);
|
||||
|
||||
if(flags.StartsWith("no-"))
|
||||
{
|
||||
currentLanguage = Language.None;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(flags)
|
||||
{
|
||||
case "fuzzy": continue;
|
||||
case "c-format":
|
||||
currentLanguage = Language.C;
|
||||
continue;
|
||||
case "objc-format":
|
||||
currentLanguage = Language.ObjectiveC;
|
||||
continue;
|
||||
case "sh-format":
|
||||
currentLanguage = Language.Shell;
|
||||
continue;
|
||||
case "python-format":
|
||||
currentLanguage = Language.Python;
|
||||
continue;
|
||||
case "python-brace-format":
|
||||
currentLanguage = Language.PythonBraced;
|
||||
continue;
|
||||
case "lisp-format":
|
||||
currentLanguage = Language.Lisp;
|
||||
continue;
|
||||
case "elisp-format":
|
||||
currentLanguage = Language.EmacsLisp;
|
||||
continue;
|
||||
case "librep-format":
|
||||
currentLanguage = Language.Librep;
|
||||
continue;
|
||||
case "scheme-format":
|
||||
currentLanguage = Language.Scheme;
|
||||
continue;
|
||||
case "smalltalk-format":
|
||||
currentLanguage = Language.Smalltalk;
|
||||
continue;
|
||||
case "java-format":
|
||||
currentLanguage = Language.Java;
|
||||
continue;
|
||||
case "csharp-format":
|
||||
currentLanguage = Language.CSharp;
|
||||
continue;
|
||||
case "awk-format":
|
||||
currentLanguage = Language.Awk;
|
||||
continue;
|
||||
case "object-pascal-format":
|
||||
currentLanguage = Language.ObjectPascal;
|
||||
continue;
|
||||
case "ycp-format":
|
||||
currentLanguage = Language.Ycp;
|
||||
continue;
|
||||
case "tcl-format":
|
||||
currentLanguage = Language.Tcl;
|
||||
continue;
|
||||
case "perl-format":
|
||||
currentLanguage = Language.Perl;
|
||||
continue;
|
||||
case "perl-brace-format":
|
||||
currentLanguage = Language.PerlBraced;
|
||||
continue;
|
||||
case "php-format":
|
||||
currentLanguage = Language.Php;
|
||||
continue;
|
||||
case "gcc-internal-format":
|
||||
currentLanguage = Language.GccInternal;
|
||||
continue;
|
||||
case "gfc-internal-format":
|
||||
currentLanguage = Language.GfcInternal;
|
||||
continue;
|
||||
case "qt-format":
|
||||
currentLanguage = Language.Qt;
|
||||
continue;
|
||||
case "qt-plural-format":
|
||||
currentLanguage = Language.QtPlural;
|
||||
continue;
|
||||
case "kde-format":
|
||||
currentLanguage = Language.Kde;
|
||||
continue;
|
||||
case "boost-format":
|
||||
currentLanguage = Language.Boost;
|
||||
continue;
|
||||
case "lua-format":
|
||||
currentLanguage = Language.Lua;
|
||||
continue;
|
||||
case "javascript-format":
|
||||
currentLanguage = Language.JavaScript;
|
||||
continue;
|
||||
default:
|
||||
currentLanguage = Language.None;
|
||||
continue;
|
||||
}
|
||||
case '|': break;
|
||||
}
|
||||
}
|
||||
|
||||
if(line.StartsWith("msgid ", StringComparison.Ordinal))
|
||||
{
|
||||
currentMsgId += line.Substring(7, line.Length - 8);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(line.StartsWith("msgstr ", StringComparison.Ordinal))
|
||||
{
|
||||
currentMsgString = line.Substring(7, line.Length - 8);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(line[0] == '"')
|
||||
{
|
||||
if(currentMsgId != string.Empty)
|
||||
{
|
||||
currentMsgString += line.Substring(1, line.Length - 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
var projectString = line.Substring(1, line.Length - 2);
|
||||
|
||||
if(projectString.StartsWith("Project-Id-Version", StringComparison.Ordinal))
|
||||
{
|
||||
var projectIdVersion = projectString.Substring(20, projectString.Length - 20);
|
||||
if(projectIdVersion.EndsWith("\\n", StringComparison.Ordinal))
|
||||
{
|
||||
projectIdVersion = projectIdVersion.Substring(0, projectIdVersion.Length - 2);
|
||||
}
|
||||
|
||||
localization.Project.Name = projectIdVersion;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(projectString.StartsWith("Report-Msgid-Bugs-To", StringComparison.Ordinal))
|
||||
{
|
||||
var projectReportTo = projectString.Substring(22, projectString.Length - 22);
|
||||
if(projectReportTo.EndsWith("\\n", StringComparison.Ordinal))
|
||||
{
|
||||
projectReportTo = projectReportTo.Substring(0, projectReportTo.Length - 2);
|
||||
}
|
||||
|
||||
localization.Project.Url = projectReportTo;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(projectString.StartsWith("Last-Translator", StringComparison.Ordinal))
|
||||
{
|
||||
var lastTranslator = projectString.Substring(17, projectString.Length - 17);
|
||||
if(lastTranslator.EndsWith("\\n", StringComparison.Ordinal))
|
||||
{
|
||||
lastTranslator = lastTranslator.Substring(0, lastTranslator.Length - 2);
|
||||
}
|
||||
|
||||
if(lastTranslator[lastTranslator.Length - 1] == '>')
|
||||
{
|
||||
var emailStart = lastTranslator.LastIndexOf('<');
|
||||
var name = lastTranslator.Substring(0, emailStart - 1);
|
||||
var email = lastTranslator.Substring(emailStart + 1,
|
||||
lastTranslator.Length - emailStart - 2);
|
||||
|
||||
currentTranslator = localization.NewTranslator(name, email);
|
||||
}
|
||||
else
|
||||
currentTranslator = localization.NewTranslator(lastTranslator, null);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(projectString.StartsWith("Language", StringComparison.Ordinal))
|
||||
{
|
||||
currentLocale = projectString.Substring(10, projectString.Length - 10);
|
||||
if(currentLocale.EndsWith("\\n", StringComparison.Ordinal))
|
||||
{
|
||||
currentLocale = currentLocale.Substring(0, currentLocale.Length - 2);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return localization;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user