- Notifications
You must be signed in to change notification settings - Fork0
A cross-platform .NET implementation of the GNU/Gettext library.
License
Urbanotopus/NGettext
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A cross-platform .NET implementation of the GNU/Gettext library.
This fully managed library works fine onMicrosoft .NET Framework version 2.0 or higher,Mono and.NET Core even on full-AOT runtimes.It is fullyCOM andCLS compatible.
This implementation loads translations directly from gettext *.mo files (no need to compile a satellite assembly) and can handle multiple translation domains and multiple locales in one application instance.NGettext supports both little-endian and big-endian MO files, automatic (header-based) encoding detection and (optional) plural form rules parsing.
By default, NGettext uses pre-compiled plural form rules for most known locales.You can enable plural form rule parsing from *.mo file headers (seeMoCompilingPluralLoader
description below)or use a custom plural rules passed to your Catalog instance through API.
There are other GNU/Gettext implementations for C#, but they all have some huge disadvantages.
Why not Mono.Unix.Catalog?Mono's Catalog is just a bindings to three native functions (bindtextdomain, gettext, and ngettext). It does not support multiple domains/locales and contexts. It is not cross-patform, it have problems with Windows OS.
Why not GNU.Gettext?It uses satellite assemblies as a translation files and does not support multiple locales in one application instance.It's hard to build and maintain translation files and change locale inside your application.
So why NGettext?
- NGettext is fully cross-platform as it doesn't use any native or managed 3rd-party libraries.
- NGettext supports multiple domains. You can separate translation files for each of your application's module or plugin.
- NGettext supports multiple locales in one application instance and gives really simple API to choose locale of your application.You don't even need to care about locales of your application's threads.
- NGettext loads translations from *.mo files. You can even load translations from specified file or stream.
- NGettext supports message contexts.
- NGettext provides nice and simple API, compatible with any type of application (console, GUI, web...).
All you need to do is just install aNuGet packagefrom the package manager console:
PM> Install-Package NGettext
or through .NET CLI utility:
$ dotnet add package NGettext
Now you can use NGettext in your code:
usingNGettext;
// This will load translations from "./locale/<CurrentUICulture>/LC_MESSAGES/Example.mo"ICatalogcatalog=newCatalog("Example","./locale");// or// This will load translations from "./locale/ru_RU/LC_MESSAGES/Example.mo"ICatalogcatalog=newCatalog("Example","./locale",newCultureInfo("ru-RU"));
Console.WriteLine(catalog.GetString("Hello, World!"));// will translate "Hello, World!" using loaded translationsConsole.WriteLine(catalog.GetString("Hello, {0}!","World"));// String.Format support
If you using this library under CoreCLR and you want to use encodings different from UTF-8 for your *.mo files, you need to includeSystem.Text.Encoding.CodePages package into your application and initialize it like this:
#ifNETCOREAPP1_0Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);#endif
// All translation methods support String.Format optional argumentscatalog.GetString("Hello, {0}!","World");// Catalog's current locale will be used to format messages correctlycatalog.GetString("Here's a number: {0}!",1.23);// Will return "Here's a number: 1.23!" for en_US locale// But something like this will be returned for ru_RU locale with Russian translation: "А вот и номер: 1,23!"
catalog.GetPluralString("You have {0} apple.","You have {0} apples.",count);// Returns (for en_US locale):// "You have {0} apple." for count = 1// "You have {0} apples." otherwisecatalog.GetPluralString("You have {0} apple.","You have {0} apples.",5,5);// Returns translated plural massage: "You have 5 apples." (for en_US locale)// First “5” used in plural forms determination; second — in String.Format method// Example plural forms usage for fractional numbers:catalog.GetPluralString("You have {0} apple.","You have {0} apples.",(long)1.23,1.23);// Internal String.Format will be used in context of catalog's locale and formats objects respectively
catalog.GetParticularString("Menu|File|","Open");// will translate message "Open" using context "Menu|File|"catalog.GetParticularString("Menu|Project|","Open");// will translate message "Open" using context "Menu|Project|"
// "./locale/en_US/LC_MESSAGES/Example.mo"ICatalogexample_en=newCatalog("Example","./locale",newCultureInfo("en-US"));// "./locale/fr/LC_MESSAGES/Example.mo"ICatalogexample_fr=newCatalog("Example","./locale",newCultureInfo("fr"));// "./locale/<CurrentUICulture>/LC_MESSAGES/AnotherDomainName.mo"ICataloganotherDomain=newCatalog("AnotherDomainName","./locale");
StreammoFileStream=File.OpenRead("path/to/domain.mo");ICatalogcatalog=newCatalog(moFileStream,newCultureInfo("en-US"));
NGettext can parse plural rules directly from the *.mo file header and compile it to a dynamic method in runtime.To enable this option you can just create a catalog using theMoCompilingPluralLoader
from theNGettext.PluralCompile package:
ICatalogcatalog=newCatalog(newMoCompilingPluralLoader("Example","./locale"));
This loader will parse plural formula from the *.mo file header and compile it to plural rule foryour Catalog instance at runtime, just when your *.mo file loads.Your Catalog's *PluralString methods performance will be the same as if you were using NGettext's default precompiled plural rules,only *.mo file loading will be slightly slower.
This feature requires enabled JIT compiler in your runtime. You can not use MoCompilingPluralLoader in an full-AOT environment.This is why MoCompilingPluralLoader moved to a separate library.
For hosts without enabled JIT you can useMoAstPluralLoader
which will only parse plural formulas to an abstract syntax treeand interpret it every time you call a *PluralString method from your catalog, without compiling.Please note that this solution is slightly slower than MoCompilingPluralLoader even it's pretty well optimized.
catalog.PluralRule=newPluralRule(numPlurals, n=>(n==1?0:1));
Also you can create custom plural rule generator by implementing IPluralRuleGenerator interface, which will createa PluralRule for any culture.
Debug version of the NGettext binary outputs debug messages to System.Diagnostics.Trace.You can register trace listeners to see NGettext debug messages.Please note that Release version of the NGettext binary does not produse any trace messages.
Trace.Listeners.Add(newTextWriterTraceListener(Console.Out));
Indoc/examples/T.cs
you can see an example of shorter syntax creation for NGettext:
T._("Hello, World!");// GetStringT._n("You have {0} apple.","You have {0} apples.",count,count);// GetPluralStringT._p("Context","Hello, World!");// GetParticularStringT._pn("Context","You have {0} apple.","You have {0} apples.",count,count);// GetParticularPluralString
ForPoedit compatibility, you need to specify plural form in your *.pot file header, even for english language:
"Plural-Forms: nplurals=2; plural=n != 1;\n"
And a keywords list:
"X-Poedit-KeywordsList: GetString;GetPluralString:1,2;GetParticularString:1c,2;GetParticularPluralString:1c,2,3;_;_n:1,2;_p:1c,2;_pn:1c,2,3\n"
Copyright (C) 2012-2016 Neris Ereptorishttp://neris.ws/.
About
A cross-platform .NET implementation of the GNU/Gettext library.
Resources
License
Stars
Watchers
Forks
Packages0
Languages
- C#100.0%