Localization Writer
Lexical.Localization.Plus class library contains writer classes, extension methods and source codes for file formats .ini, .xml, .json, .resx, and .resources.
Format | Writer |
---|---|
.ini | IniLinesWriter |
.json | JsonLinesWriter |
.xml | XmlLinesWriter |
.resx | ResxLinesWriter |
.resources | ResourcesLinesWriter |
Writer classes inherit their respecctive reader classes, and thus have reader features as well.
LineWriterMap is a dictionary that contains default writer classes.
ILineFileFormat format = LineWriterMap.Default["ini"];
Writers can also be acquired from the singleton instances.
ILineFileFormat format = IniLinesWriter.Default;
Writing Lines
If file format can be inferred from file extension, then content can be written with LineWriterMap.
.WriteLines() writes IEnumerable<ILine> lines to a file.
IEnumerable<ILine> lines = new List<ILine>
{
LineAppender.NonResolving.Culture("en").Type("Class").Key("Hello").Format("Hello World!")
};
LineWriterMap.Default.WriteLines(
lines,
srcFilename: null,
dstFilename: "localization1.ini",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
IniLinesWriter writes lines as .ini file format.
IniLinesWriter.Default.WriteLines(
lines,
srcFilename: null,
dstFilename: "localization1.ini",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
JsonLinesWriter writes lines as .json file format.
JsonLinesWriter.Default.WriteLines(
lines,
srcFilename: null,
dstFilename: "localization1.json",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
XmlLinesWriter writes lines as .xml file format.
XmlLinesWriter.Default.WriteLines(
lines,
srcFilename: null,
dstFilename: "localization1.xml",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
ResxLinesWriter writes lines as .resx file format. ILineFormat is required in order to formulate key into string.
ResxLinesWriter.Default.WriteLines(
lines,
srcFilename: null,
dstFilename: "localization1.resx",
lineFormat: LineParameterPrinter.Default,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
ResourcesLinesWriter writes lines as .resources file format.
ResourcesLinesWriter.Default.WriteLines(
lines,
srcFilename: null,
dstFilename: "localization1.resources",
lineFormat: LineParameterPrinter.Default,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
LinePattern can be used for formulating how lines are grouped into levels when writing to structural file format. File formats .json and .xml have a tree structure, and .ini has shallow two level structure.
// Create lines
IEnumerable<ILine> lines = new List<ILine> {
LineAppender.NonResolving.Culture("en")
.Section("Section1").Section("Section2").Type("Class").Key("Hello").N("Plural")
.Format("Hello {0} worlds!")
};
// Grouping rule: Everything on one level. If culture is provided, then on its own level.
ILineFormat grouping = new LinePattern("{Section}{Type}[Key]{/Culture}");
string text = XmlLinesWriter.Default.WriteLinesAsString(
lines,
srcText: null,
lineFormat: grouping,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
"/" divides a key into levels.
// Grouping rule: Culture on first level. Each section in one level. Type, key and rest on last level.
ILineFormat grouping = new LinePattern("{Culture}/{Section}/{Type}[Key]");
string text = XmlLinesWriter.Default.WriteLinesAsString(
lines,
srcText: null,
lineFormat: grouping,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
If the separator "/" is inside a capture part, e.g. "{/Section}", then each occurance of the key part starts a new level.
ILine key = LineAppender.NonResolving.Culture("en").Section("Section1").Section("Section2").Type("Class").Key("Hello").N("Plural");
IEnumerable<ILine> lines = new List<ILine> { key.Format("Hello {0} worlds!") };
// Grouping rule: Culture on first level. Each section in own level. Type, key and rest on last level.
ILineFormat grouping = new LinePattern("{Culture}/{Section/}{Type}[Key]");
string text = XmlLinesWriter.Default.WriteLinesAsString(
lines,
srcText: null,
lineFormat: grouping,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
Writing String Key Lines
.WriteUnformedLines() writes from IEnumerable<KeyValuePair<string, IString>> lines to a file.
IEnumerable<KeyValuePair<string, IString>> lines = new Dictionary<string, IString>
{
{ "en.MyController.Hello", CSharpFormat.Default.Parse("Hello World!") }
};
ILineFormat policy = new LinePattern("{culture.}[Type.]{Key}[.Key_n]");
LineWriterMap.Default.WriteUnformedLines(
lines,
srcFilename: null,
dstFilename: "localization1.ini",
lineFormat: policy,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
IniLinesWriter writes lines as .ini file format. ILineFormat is required to formulate key into string.
IniLinesWriter.Default.WriteUnformedLines(
lines,
srcFilename: null,
dstFilename: "localization1.ini",
lineFormat: policy,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
JsonLinesWriter writes lines as .json file format.
JsonLinesWriter.Default.WriteUnformedLines(
lines,
srcFilename: null,
dstFilename: "localization1.json",
lineFormat: policy,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
XmlLinesWriter writes lines as .xml file format.
XmlLinesWriter.Default.WriteUnformedLines(
lines,
srcFilename: null,
dstFilename: "localization1.xml",
lineFormat: policy,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
ResxLinesWriter writes lines as .resx file format. ILineFormat is not used.
ResxLinesWriter.Default.WriteUnformedLines(
lines,
srcFilename: null,
dstFilename: "localization1.resx",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
ResourcesLinesWriter writes lines as .resources file format.
ResourcesLinesWriter.Default.WriteUnformedLines(
lines,
srcFilename: null,
dstFilename: "localization1.resources",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
Writing Key Tree
.WriteLineTree() writes structurally from structural ILineTree to a file.
ILineTree tree = new LineTree();
ILineTree level1 = tree.Create(LineAppender.NonResolving.Culture("en"));
ILineTree level2 = level1.Create(LineAppender.NonResolving.Type("Class"));
ILineTree level3 = level2.Create(LineAppender.NonResolving.Key("Hello"));
level3.AddValue("Hello World!");
LineWriterMap.Default.WriteLineTree(
tree,
srcFilename: null,
dstFilename: "localization1.ini",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
IniLinesWriter writes tree as .ini file format, but flattens levels after second.
ILineTree tree = new LineTree();
ILineTree level1 = tree.Create(LineAppender.NonResolving.Culture("en"));
ILineTree level2 = level1.Create(LineAppender.NonResolving.Type("Class"));
ILineTree level3 = level2.Create(LineAppender.NonResolving.Key("Hello"));
level3.AddValue("Hello World!");
LineWriterMap.Default.WriteLineTree(
tree,
srcFilename: null,
dstFilename: "localization1.ini",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
JsonLinesWriter writes tree as .json file format.
LineWriterMap.Default.WriteLineTree(
tree,
srcFilename: null,
dstFilename: "localization1.json",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
XmlLinesWriter writes tree as .xml file format.
LineWriterMap.Default.WriteLineTree(
tree,
srcFilename: null,
dstFilename: "localization1.xml",
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
ResxLinesWriter writes tree as .resx file format. ILineFormat is required in order to formulate key into string.
LineWriterMap.Default.WriteLineTree(
tree,
srcFilename: null,
dstFilename: "localization1.resx",
lineFormat: LineParameterPrinter.Default,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
ResourcesLinesWriter writes tree as .resources file format.
LineWriterMap.Default.WriteLineTree(
tree,
srcFilename: null,
dstFilename: "localization1.resources",
lineFormat: LineParameterPrinter.Default,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
Writing to Stream
Lines can be written to Stream.
Stream stream = new MemoryStream();
IniLinesWriter.Default.WriteLines(
lines,
srcStream: null,
dstStream: stream,
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
Writing to TextWriter
Lines can be written to TextWriter.
TextWriter textWriter = new StringWriter();
IniLinesWriter.Default.WriteLines(
lines,
srcText: null,
dstText: textWriter,
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
Writing to String
Lines can be written to String.
string text = IniLinesWriter.Default.WriteLinesAsString(
lines,
srcText: null,
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Overwrite);
Update File
Existing files can be updated. LineFileWriteFlags determines what kind of changes are allowed.
// Source
string text =
@"; Comment\n" +
@"[Type:MyController]\n" +
@"Key:Hello = Hello World\n";
// Read lines
List<ILine> lines = IniLinesWriter.Default.ReadString(text).ToList();
// Add line
lines.Add(LineAppender.NonResolving.Culture("de").Type("Class").Key("Hello").Format("Hallo Welt"));
// Update
string newText = IniLinesWriter.Default.WriteLinesAsString(
lines,
srcText: text,
lineFormat: null,
flags: LineFileWriteFlags.Add | LineFileWriteFlags.Modify |
LineFileWriteFlags.Remove | LineFileWriteFlags.EffectiveKeyMatching);
LineFileWriteFlags | Description |
---|---|
Add | Permission to add new entries to the container. |
Remove | Permission to remove entires that no longer exist. Entry is removed recursively. |
RemoveCautious | Permission to remove entires that no longer exist, but be cautious. If entry contains unrecognized comments, elements, then entry is not removed recursively. |
Modify | Permission to modify values of existing entries. |
Overwrite | Overwrite contents of previous file. Add flag is required to be used with Overwrite. |
EffectiveKeyMatching | Matches when old and new files have different tree structure. |
Implementing
ILineWriter is the root interface for localization writer classes. (Click here)
A class that implements ILineWriter must to implement one of its sub-interfaces. A one that best suits the underlying format.
class ExtFileFormatWriter : IUnformedLineTextWriter
{
public string Extension => "ext";
public void WriteUnformedLines(IEnumerable<KeyValuePair<string, IString>> lines, TextReader srcText, TextWriter dstText, ILineFormat lineFormat, LineFileWriteFlags flags)
{
foreach (var line in lines)
{
dstText.WriteLine($"{line.Key} = {line.Value.Text}");
}
}
}
Writer can be added to LineWriterMap
// Create writer
ILineWriter format = new ExtFileFormatWriter();
// Clone formats
LineFileFormatMap formats = LineWriterMap.Default.Clone();
// Add to clone
formats.Add(format);
// Or if in deploying application project, format can be added to the global singleton
(LineWriterMap.Default as IDictionary<string, ILineFileFormat>).Add(format);