ILine is a localization line. It can be embedded with a default string.
ILine line = LineRoot.Global.Type("MyClass").Key("hello").Format("Hello, {0}.");
Values are provided with .Value(object[]).
Console.WriteLine(line.Value("Corellia Melody"));
Providing .Format() and .Value() is equivalent to String.Format().
Console.WriteLine(LineRoot.Global.Format("It is now {0:d} at {0:t}").Value(DateTime.Now));
Console.WriteLine(String.Format("It is now {0:d} at {0:t}", DateTime.Now));
.Formulate($string) appends interpolated strings. It's equivalent to appending .Format() and .Value() parts.
DateTime time = DateTime.Now;
Console.WriteLine(LineRoot.Global.Key("Time").Formulate($"It is now {time:d} at {time:t}"));
Enumeration localization strings are searched with key "Assembly:asm:Type:enumType:Key:enumCase".
Permissions permissions = Permissions.Add | Permissions.Modify | Permissions.Remove;
Console.WriteLine( LineRoot.Global.Key("Permission").Formulate($"User permissions {permissions}") );
[Flags]
public enum Permissions { Add = 1, Remove = 2, Modify = 4 }
The format culture can be enforced with .Culture(CultureInfo), without changing the thread-local culture variable.
Console.WriteLine(LineRoot.Global.Format("It is now {0:d} at {0:t}").Culture("sv").Value(DateTime.Now));
Console.WriteLine(LineRoot.Global.Format("It is now {0:d} at {0:t}").Culture("de").Value(DateTime.Now));
Default strings can be inlined for multiple cultures.
ILine line = LineRoot.Global
.Key("hello")
.Format("Hello, {0}.")
.Inline("Culture:fi", "Hei, {0}")
.Inline("Culture:de", "Hallo, {0}");
Console.WriteLine(line.Value("Corellia Melody"));
And inlined with different plurality cases.
ILine line = LineRoot.Global.PluralRules("Unicode.CLDR35")
.Type("MyClass").Key("Cats")
.Format("{cardinal:0} cat(s)")
.Inline("N:zero", "no cats")
.Inline("N:one", "a cat")
.Inline("N:other", "{0} cats");
for (int cats = 0; cats <= 2; cats++)
Console.WriteLine(line.Value(cats));
And with permutations of different cultures and plurality cases.
ILine line = LineRoot.Global.PluralRules("Unicode.CLDR35")
.Type("MyClass").Key("Cats")
.Format("{0} cat(s)")
.Inline("Culture:en", "{cardinal:0} cat(s)")
.Inline("Culture:en:N:zero", "no cats")
.Inline("Culture:en:N:one", "a cat")
.Inline("Culture:en:N:other", "{0} cats")
.Inline("Culture:fi", "{cardinal:0} kissa(a)")
.Inline("Culture:fi:N:zero", "ei kissoja")
.Inline("Culture:fi:N:one", "yksi kissa")
.Inline("Culture:fi:N:other", "{0} kissaa");
// Print with plurality and to culture "en"
for (int cats = 0; cats <= 2; cats++)
Console.WriteLine(line.Culture("en").Value(cats));
Localization assets can be read from files and placed into the global LineRoot.Global.
IAsset asset = LineReaderMap.Default.FileAsset("PluralityExample0a.xml");
LineRoot.Builder.AddAsset(asset).Build();
ILine line = LineRoot.Global.Key("Cats").Format("{0} cat(s)");
// Print with plurality
for (int cats = 0; cats <= 2; cats++)
Console.WriteLine(line.Culture("fi").Value(cats));
PluralityExample0a.xml (click here)
<?xml version="1.0" encoding="UTF-8"?>
<Localization xmlns:Culture="urn:lexical.fi:Culture"
xmlns:Key="urn:lexical.fi:Key"
xmlns:N="urn:lexical.fi:N"
xmlns="urn:lexical.fi"
PluralRules="Unicode.CLDR35">
<!-- Fallback string, for "" culture -->
<Key:Cats>{0} cat(s)</Key:Cats>
<!-- Translator added strings for "en" -->
<Key:Cats Culture="en">
{cardinal:0} cat(s)
<N:zero>no cats</N:zero>
<N:one>a cat</N:one>
<N:other>{0} cats</N:other>
</Key:Cats>
<!-- Translator added strings for "fi" -->
<Key:Cats Culture="fi">
{cardinal:0} kissa(a)
<N:zero>ei kissoja</N:zero>
<N:one>yksi kissa</N:one>
<N:other>{0} kissaa</N:other>
</Key:Cats>
</Localization>
Or, assets can be loaded and placed into a new ILineRoot.
IAsset asset = LineReaderMap.Default.FileAsset("PluralityExample0a.xml");
ILineRoot root = new LineRoot(asset, new CulturePolicy());
ILine line = root.Key("Cats").Format("{0} cat(s)");
IAsset is an abstraction to localization lines and localized resources. Implementing classes can be provided within code.
List<ILine> lines = new List<ILine> {
LineAppender.Default.Type("MyClass").Key("Hello").Format("Hello, {0}"),
LineAppender.Default.Type("MyClass").Key("Hello").Culture("fi").Format("Hei, {0}"),
LineAppender.Default.Type("MyClass").Key("Hello").Culture("de").Format("Hallo, {0}")
};
IAsset asset = new StringAsset().Add(lines).Load();
ILineRoot root = new LineRoot(asset, new CulturePolicy());
ILine line = root.Type("MyClass").Key("Hello");
Console.WriteLine(line.Value("Corellia Melody"));
Loggers can be appended to ILine for debugging purposes.
ILine root = LineRoot.Global.Logger(Console.Out, LineStatusSeverity.Ok);
ILine line = root.Type("MyClass").Key("hello").Format("Hello, {0}.");
Console.WriteLine(line.Value("Corellia Melody"));
Different string formats, such as C#'s String.Format, are supported. IStringFormat is an abstraction to string formats.
ILine line1a = LineRoot.Global.Key("Cats").Format("{0} cat(s)");
IString string1 = CSharpFormat.Default.Parse("{0} cat(s)");
ILine line1b = LineRoot.Global.Key("Cats").String(string1);
ILine line2a = LineRoot.Global.Key("Ok").Text("{in braces}");
IString string2 = TextFormat.Default.Parse("{in braces}");
ILine line2b = LineRoot.Global.Key("Ok").String(string2);
ICulturePolicy determines which culture to apply.
ICulturePolicy culturePolicy = new CulturePolicy().SetToCurrentThreadUICulture();
ILine root = new LineRoot(null, culturePolicy: culturePolicy);
ILine.ResolveString() returns more information about the string resolve process than ILine.ToString().
LineString resolved_string = line.Value("Corellia Melody").ResolveString();
Console.WriteLine(resolved_string.Status);
StringLocalizerRoot.Global is same root as LineRoot.Global with the difference, that parts derived from it implement IStringLocalizer and IStringLocalizerFactory.
ILine line = StringLocalizerRoot.Global.Type("MyClass").Key("hello").Format("Hello, {0}.");
IStringLocalizer localizer = line.AsStringLocalizer();
IStringLocalizerFactory localizerFactory = line.AsStringLocalizerFactory();
New StringLocalizerRoot can also be constructed.
ILineRoot root = new StringLocalizerRoot(null, new CulturePolicy());
ILine line = root.Type("MyClass").Key("hello").Format("Hello, {0}.");
IStringLocalizer localizer = line.AsStringLocalizer();
IStringLocalizerFactory localizerFactory = line.AsStringLocalizerFactory();
IStringLocalizer reference can be adapted from regular LineRoot as well, but causes an additional heap object to be instantiated.
ILine line = LineRoot.Global.Type("MyClass").Key("hello").Format("Hello, {0}.");
IStringLocalizer localizer = line.AsStringLocalizer();
IStringLocalizerFactory localizerFactory = line.AsStringLocalizerFactory();
Keys can be placed in static references if the singleton LineRoot.Global is used.
public class MyClass
{
/// <summary>
/// Localization root for this class.
/// </summary>
static ILine localization = LineRoot.Global.Assembly("MyLibrary").Type<MyClass>();
/// <summary>
/// Localization key "Ok" with a default string, and couple of inlined strings for two cultures.
/// </summary>
static ILine ok = localization.Key("Success")
.Text("Success")
.fi("Onnistui")
.sv("Det funkar");
/// <summary>
/// Localization key "Error" with a default string, and couple of inlined ones for two cultures.
/// </summary>
static ILine error = localization.Key("Error")
.Format("Error (Code=0x{0:X8})")
.fi("Virhe (Koodi=0x{0:X8})")
.sv("Sönder (Kod=0x{0:X8})");
public void DoOk()
{
Console.WriteLine(ok);
}
public void DoError()
{
Console.WriteLine(error.Value(0x100));
}
public void DoExample()
{
string msg = "";
Console.WriteLine(localization.Key("Msg").Formulate($"You received a message: \"{msg}\""));
}
}