From 0ff7bb68c45e7351aab471d9cec39dcd3c4639ca Mon Sep 17 00:00:00 2001 From: Tony Bark Date: Sun, 13 Dec 2020 07:48:15 -0500 Subject: [PATCH] UIText class The UIText class allows for travseing in "//.dir" directories and searching for CST files by their Id number. See usage.md for more info. --- .editorconfig | 7 +- .../{ => ISSUE_TEMPLATE}/ISSUE_TEMPLATE.md | 0 .github/workflows/dotnet.yml | 5 +- CSTNet.Tests/CSTHelper.cs | 16 --- CSTNet.sln.licenseheader | 3 - CSTNet/Sixam.CST.csproj | 14 --- README.md | 25 +--- .../MultilineTests.cs | 11 +- .../SingleLineTests.cs | 9 +- .../Sixam.CST.Tests.csproj | 6 +- .../uitext/lorem.dir/_101_v1.cst | 0 Sixam.CST.Tests/uitext/lorem.dir/_102_v2.cst | 4 + Sixam.CST.sln | 24 ++-- Sixam.CST.sln.licenseheader | 4 + {CSTNet => Sixam.CST}/CaretSeparatedText.cs | 62 +++++----- Sixam.CST/Sixam.CST.csproj | 16 +++ Sixam.CST/UIText.cs | 57 +++++++++ changelog.md | 17 +++ notebooks/cst.ipynb | 110 +++++++++--------- notebooks/data/uitext/english.dir/_101_v1.cst | 8 ++ .../data/uitext/english.dir/_102_v2.cst | 0 usage.md | 61 ++++++++++ 22 files changed, 289 insertions(+), 170 deletions(-) rename .github/{ => ISSUE_TEMPLATE}/ISSUE_TEMPLATE.md (100%) delete mode 100644 CSTNet.Tests/CSTHelper.cs delete mode 100644 CSTNet.sln.licenseheader delete mode 100644 CSTNet/Sixam.CST.csproj rename {CSTNet.Tests => Sixam.CST.Tests}/MultilineTests.cs (79%) rename {CSTNet.Tests => Sixam.CST.Tests}/SingleLineTests.cs (83%) rename {CSTNet.Tests => Sixam.CST.Tests}/Sixam.CST.Tests.csproj (86%) rename CSTNet.Tests/v1.cst => Sixam.CST.Tests/uitext/lorem.dir/_101_v1.cst (100%) create mode 100644 Sixam.CST.Tests/uitext/lorem.dir/_102_v2.cst create mode 100644 Sixam.CST.sln.licenseheader rename {CSTNet => Sixam.CST}/CaretSeparatedText.cs (56%) create mode 100644 Sixam.CST/Sixam.CST.csproj create mode 100644 Sixam.CST/UIText.cs create mode 100644 notebooks/data/uitext/english.dir/_101_v1.cst rename CSTNet.Tests/v2.cst => notebooks/data/uitext/english.dir/_102_v2.cst (100%) create mode 100644 usage.md diff --git a/.editorconfig b/.editorconfig index d19f873..45a6ca1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -29,7 +29,7 @@ dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pasca dotnet_naming_symbols.constant_fields.applicable_kinds = field dotnet_naming_symbols.constant_fields.required_modifiers = const -dotnet_naming_style.pascal_case_style.capitalization = pascal_case +dotnet_naming_style.pascal_case_style.capitalization = all_upper # Comment this group and uncomment out the next group if you don't want _ prefixed fields. @@ -125,7 +125,4 @@ csharp_space_between_method_declaration_empty_parameter_list_parentheses = false csharp_space_between_method_declaration_name_and_open_parenthesis = false csharp_space_between_method_declaration_parameter_list_parentheses = false csharp_space_between_parentheses = false -csharp_space_between_square_brackets = false - -# CA1815: Override equals and operator equals on value types -dotnet_diagnostic.CA1815.severity = silent +csharp_space_between_square_brackets = false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md similarity index 100% rename from .github/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2bb59f8..341e246 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -2,10 +2,9 @@ name: .NET on: push: - branches: [master, develop] + branches: [master, "releases/**"] pull_request: - branches: [master, develop] - + branches: [master, "releases/**"] jobs: build: runs-on: ubuntu-latest diff --git a/CSTNet.Tests/CSTHelper.cs b/CSTNet.Tests/CSTHelper.cs deleted file mode 100644 index e203e46..0000000 --- a/CSTNet.Tests/CSTHelper.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.IO; - -namespace CSTNet.Tests -{ - static class CSTHelper - { - public static string CSTFile(string cst, string key) - { - var path = Path.Combine(AppContext.BaseDirectory, cst); - var file = File.ReadAllText(path); - - return CaretSeparatedText.Parse(file, key); - } - } -} diff --git a/CSTNet.sln.licenseheader b/CSTNet.sln.licenseheader deleted file mode 100644 index 167f123..0000000 --- a/CSTNet.sln.licenseheader +++ /dev/null @@ -1,3 +0,0 @@ -extensions: designer.cs generated.cs -extensions: .cs .cpp .h -// This project is licensed under the MIT license. \ No newline at end of file diff --git a/CSTNet/Sixam.CST.csproj b/CSTNet/Sixam.CST.csproj deleted file mode 100644 index 129d2db..0000000 --- a/CSTNet/Sixam.CST.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - netstandard2.0 - 1.0.2 - Tony Bark - Caret-Separated Text (or CST) is a key-value pair format represented by numbers or words as keys and the value is the string enclosed between carets (^) that contains the contents. CST.NET is a library for prasing the CST format. - https://github.com/sixamsoft/cst-dotnet - MIT - CST.Net - CSTNet - - - diff --git a/README.md b/README.md index e6b301a..3d180c1 100644 --- a/README.md +++ b/README.md @@ -6,30 +6,7 @@ Caret-Separated Text (or CST) is a key-value pair format represented by digits o ## Usage -```text -1 ^The quick brown fox jumps over the lazy dog.^ -``` - -```csharp -#r "nuget:CSTNet,1.0.2" -using System; -using System.IO; -using CSTNet; - -var file = File.ReadAllText("example.cst"); -var example = CaretSeparatedText.Parse(file, 1); - -Console.WriteLine(example); -``` - -See working example on [.NET Fiddle](https://dotnetfiddle.net/ecKb2h). - -In production, CST files were used in The Sims Online (TSO) to provide translations. Each translation was split into their respective directories: - -- ``uitext/english.dir/_154_miscstrings.cst`` -- ``uitext/swedish.dir/_154_miscstrings.cst`` - -Sixam.CST only provides the basic parsing functionality. +See [usage.md](./usage.md). ## To-do diff --git a/CSTNet.Tests/MultilineTests.cs b/Sixam.CST.Tests/MultilineTests.cs similarity index 79% rename from CSTNet.Tests/MultilineTests.cs rename to Sixam.CST.Tests/MultilineTests.cs index 4db5f89..e1a0c5e 100644 --- a/CSTNet.Tests/MultilineTests.cs +++ b/Sixam.CST.Tests/MultilineTests.cs @@ -1,16 +1,18 @@ +// This project is licensed under the MIT license. +// See the LICENSE file in the project root for more information. using System; using Xunit; -namespace CSTNet.Tests +namespace Sixam.CST.Tests { public class MultilineTests { [Fact] public void MiltilineV1() { - var four = 4; var expected = $"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce justo dui, rhoncus a pulvinar sit amet, fermentum vitae lorem. Maecenas nec nisi sit amet eros rutrum congue. In sagittis suscipit arcu, ac vestibulum nunc feugiat volutpat.{Environment.NewLine}{Environment.NewLine}Vivamus consequat velit dui, sit amet rhoncus dui malesuada a. Maecenas hendrerit commodo mi et scelerisque. Cras pharetra ultrices aliquam. Praesent ac efficitur magna, vitae scelerisque metus."; - var actual = CSTHelper.CSTFile("v1.cst", four.ToString()); + var lorem = new UIText("lorem"); + var actual = lorem.GetText(101, 4); Assert.Equal(expected, actual); } @@ -18,7 +20,8 @@ namespace CSTNet.Tests public void MiltilineV2() { var expected = $"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc gravida nunc non justo pretium consectetur. Sed tempus libero ac ligula aliquam elementum. Duis vitae interdum leo. Sed semper nulla %1 a lectus dictum dictum.{Environment.NewLine}{Environment.NewLine}Quisque vehicula, nisi ut scelerisque sodales, nisi ipsum sodales ipsum, in rutrum tellus lacus sed nibh. Etiam mauris velit, elementum sed placerat et, elementum et tellus. Duis vitae elit fermentum, viverra lorem in, lobortis elit."; - var actual = CSTHelper.CSTFile("v2.cst", "Multiline"); + var lorem = new UIText("lorem"); + var actual = lorem.GetText(102, "Multiline"); Assert.Equal(expected, actual); } } diff --git a/CSTNet.Tests/SingleLineTests.cs b/Sixam.CST.Tests/SingleLineTests.cs similarity index 83% rename from CSTNet.Tests/SingleLineTests.cs rename to Sixam.CST.Tests/SingleLineTests.cs index bc217f9..03b9a9b 100644 --- a/CSTNet.Tests/SingleLineTests.cs +++ b/Sixam.CST.Tests/SingleLineTests.cs @@ -1,7 +1,8 @@ // This project is licensed under the MIT license. +// See the LICENSE file in the project root for more information. using Xunit; -namespace CSTNet.Tests +namespace Sixam.CST.Tests { public class SingleLineTests { @@ -10,7 +11,8 @@ namespace CSTNet.Tests [InlineData(3, @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam venenatis ac odio ut pretium. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec semper turpis tempor, bibendum sapien at, blandit neque. Vivamus hendrerit imperdiet elit, vel sollicitudin nulla luctus vel. Vivamus nisl quam, feugiat a diam aliquam, iaculis vestibulum nunc. Maecenas euismod leo enim, faucibus ultrices ipsum semper eu. Praesent ullamcorper justo at maximus ultricies.")] public void V1Test(int key, string expected) { - var actual = CSTHelper.CSTFile("v1.cst", key.ToString()); + var lorem = new UIText("lorem"); + var actual = lorem.GetText(101, key); Assert.Equal(expected, actual); } @@ -18,7 +20,8 @@ namespace CSTNet.Tests [InlineData("Singleline", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ultricies nulla eu tortor mattis, dictum posuere lacus ornare. Maecenas a massa in ligula finibus luctus eu vitae nibh. Proin imperdiet dapibus mauris quis placerat.")] public void V2Test(string key, string expected) { - var actual = CSTHelper.CSTFile("v2.cst", key); + var lorem = new UIText("lorem"); + var actual = lorem.GetText(102, key); Assert.Equal(expected, actual); } } diff --git a/CSTNet.Tests/Sixam.CST.Tests.csproj b/Sixam.CST.Tests/Sixam.CST.Tests.csproj similarity index 86% rename from CSTNet.Tests/Sixam.CST.Tests.csproj rename to Sixam.CST.Tests/Sixam.CST.Tests.csproj index fbc2709..7baa57a 100644 --- a/CSTNet.Tests/Sixam.CST.Tests.csproj +++ b/Sixam.CST.Tests/Sixam.CST.Tests.csproj @@ -19,14 +19,14 @@ - + - + PreserveNewest - + PreserveNewest diff --git a/CSTNet.Tests/v1.cst b/Sixam.CST.Tests/uitext/lorem.dir/_101_v1.cst similarity index 100% rename from CSTNet.Tests/v1.cst rename to Sixam.CST.Tests/uitext/lorem.dir/_101_v1.cst diff --git a/Sixam.CST.Tests/uitext/lorem.dir/_102_v2.cst b/Sixam.CST.Tests/uitext/lorem.dir/_102_v2.cst new file mode 100644 index 0000000..773bc88 --- /dev/null +++ b/Sixam.CST.Tests/uitext/lorem.dir/_102_v2.cst @@ -0,0 +1,4 @@ +Singleline^Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ultricies nulla eu tortor mattis, dictum posuere lacus ornare. Maecenas a massa in ligula finibus luctus eu vitae nibh. Proin imperdiet dapibus mauris quis placerat.^ +Multiline ^Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc gravida nunc non justo pretium consectetur. Sed tempus libero ac ligula aliquam elementum. Duis vitae interdum leo. Sed semper nulla %1 a lectus dictum dictum. + +Quisque vehicula, nisi ut scelerisque sodales, nisi ipsum sodales ipsum, in rutrum tellus lacus sed nibh. Etiam mauris velit, elementum sed placerat et, elementum et tellus. Duis vitae elit fermentum, viverra lorem in, lobortis elit.^ \ No newline at end of file diff --git a/Sixam.CST.sln b/Sixam.CST.sln index a166832..1ffbbed 100644 --- a/Sixam.CST.sln +++ b/Sixam.CST.sln @@ -3,16 +3,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30717.126 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sixam.CST", "CSTNet\Sixam.CST.csproj", "{82775826-A366-46F0-A5D2-5BE7658C75E4}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CCFCE2DB-C18F-4D88-B025-19ED62BD2A1D}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig changelog.md = changelog.md README.md = README.md + Sixam.CST.sln.licenseheader = Sixam.CST.sln.licenseheader + usage.md = usage.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sixam.CST.Tests", "CSTNet.Tests\Sixam.CST.Tests.csproj", "{B6A98C64-1419-4B9A-99CA-72BB11D29472}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sixam.CST", "Sixam.CST\Sixam.CST.csproj", "{C5372E74-D1DF-4D15-B597-D1F517ECD0D8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sixam.CST.Tests", "Sixam.CST.Tests\Sixam.CST.Tests.csproj", "{01A1A8E9-D83E-4877-8AEB-2FD0A298F049}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -20,14 +22,14 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {82775826-A366-46F0-A5D2-5BE7658C75E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {82775826-A366-46F0-A5D2-5BE7658C75E4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {82775826-A366-46F0-A5D2-5BE7658C75E4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {82775826-A366-46F0-A5D2-5BE7658C75E4}.Release|Any CPU.Build.0 = Release|Any CPU - {B6A98C64-1419-4B9A-99CA-72BB11D29472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B6A98C64-1419-4B9A-99CA-72BB11D29472}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B6A98C64-1419-4B9A-99CA-72BB11D29472}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B6A98C64-1419-4B9A-99CA-72BB11D29472}.Release|Any CPU.Build.0 = Release|Any CPU + {C5372E74-D1DF-4D15-B597-D1F517ECD0D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5372E74-D1DF-4D15-B597-D1F517ECD0D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5372E74-D1DF-4D15-B597-D1F517ECD0D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5372E74-D1DF-4D15-B597-D1F517ECD0D8}.Release|Any CPU.Build.0 = Release|Any CPU + {01A1A8E9-D83E-4877-8AEB-2FD0A298F049}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01A1A8E9-D83E-4877-8AEB-2FD0A298F049}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01A1A8E9-D83E-4877-8AEB-2FD0A298F049}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01A1A8E9-D83E-4877-8AEB-2FD0A298F049}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Sixam.CST.sln.licenseheader b/Sixam.CST.sln.licenseheader new file mode 100644 index 0000000..df4e2e0 --- /dev/null +++ b/Sixam.CST.sln.licenseheader @@ -0,0 +1,4 @@ +extensions: designer.cs generated.cs +extensions: .cs .cpp .h +// This project is licensed under the MIT license. +// See the LICENSE file in the project root for more information. \ No newline at end of file diff --git a/CSTNet/CaretSeparatedText.cs b/Sixam.CST/CaretSeparatedText.cs similarity index 56% rename from CSTNet/CaretSeparatedText.cs rename to Sixam.CST/CaretSeparatedText.cs index 8c7a81a..1346f67 100644 --- a/CSTNet/CaretSeparatedText.cs +++ b/Sixam.CST/CaretSeparatedText.cs @@ -1,26 +1,24 @@ // This project is licensed under the MIT license. +// See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; +using System.Linq; -namespace CSTNet +namespace Sixam.CST { - public static class CaretSeparatedText + public class CaretSeparatedText { const char CARET = '^'; - static readonly string _lf = "\u000A"; - static readonly string _cr = "\u000D"; - static readonly string _crlf = "\u000D\u000A"; - static readonly string _ls = "\u2028"; + const string LF = "\u000A"; + const string CR = "\u000D"; + const string CRLF = "\u000D\u000A"; + const string LS = "\u2028"; /// - /// Gets the value from the integer-based key. + /// Gets the value from the digit-based key. /// /// Returns the entry - public static string Parse(string content, int key) - { - var entries = NormalizeEntries(content); - return GetEntry(entries, key.ToString()); - } + public static string Parse(string content, int key) => Parse(content, key.ToString()); /// /// Gets the value from the string-based key. @@ -40,34 +38,28 @@ namespace CSTNet { if (!content.Contains(Environment.NewLine)) { - if (content.Contains(_lf)) - content = content.Replace(_lf, Environment.NewLine); + if (content.Contains(LF)) + content = content.Replace(LF, Environment.NewLine); - if (content.Contains(_cr)) - content = content.Replace(_cr, Environment.NewLine); + if (content.Contains(CR)) + content = content.Replace(CR, Environment.NewLine); - if (content.Contains(_crlf)) - content = content.Replace(_crlf, Environment.NewLine); + if (content.Contains(CRLF)) + content = content.Replace(CRLF, Environment.NewLine); - if (content.Contains(_ls)) - content = content.Replace(_ls, Environment.NewLine); + if (content.Contains(LS)) + content = content.Replace(LS, Environment.NewLine); } var lines = content.Split(new[] { $"{CARET}{Environment.NewLine}" }, StringSplitOptions.RemoveEmptyEntries); - var entries = new List(); - foreach (var line in lines) - { - // Skip comments - if (line.StartsWith("//") || line.StartsWith("#") || - line.StartsWith("/*") || line.EndsWith("*/")) - continue; - - entries.Add(line); - } - - return entries; + return lines.Where(line => + !line.StartsWith("//") && + !line.StartsWith("#") && + !line.StartsWith("/*") && + !line.EndsWith("*/")) + .AsEnumerable(); } static string GetEntry(IEnumerable entries, string key) @@ -90,3 +82,9 @@ namespace CSTNet } } } + +namespace CSTNet +{ + [Obsolete("Use the Sixam.CST namespace instead.")] + public class CaretSeparatedText : Sixam.CST.CaretSeparatedText { } +} diff --git a/Sixam.CST/Sixam.CST.csproj b/Sixam.CST/Sixam.CST.csproj new file mode 100644 index 0000000..65d3755 --- /dev/null +++ b/Sixam.CST/Sixam.CST.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.0 + 1.1.100 + Tony Bark, Sixam Software + + Caret-Separated Text (or CST) is a key-value pair format represented by digits or words as keys and the value as text enclosed between carets. ([key] ^[value]^) + + Sixam.CST provides you the framework for parsing the CST format. + + https://github.com/sixamsoft/cst-dotnet + MIT + + + diff --git a/Sixam.CST/UIText.cs b/Sixam.CST/UIText.cs new file mode 100644 index 0000000..b091f04 --- /dev/null +++ b/Sixam.CST/UIText.cs @@ -0,0 +1,57 @@ +// This project is licensed under the MIT license. +// See the LICENSE file in the project root for more information. +using System; +using System.IO; + +namespace Sixam.CST +{ + public class UIText + { + string Language { get; set; } = "english"; + public string[] BasePath { get; set; } = { AppContext.BaseDirectory, "uitext" }; + + public UIText() { } + + public UIText(string language) + { + Language = language; + } + + public UIText(string language, params string[] baseBath) + { + Language = language; + BasePath = baseBath; + } + + public string GetText(int id, int key) => GetText(id, key.ToString()); + + public string GetText(int id, string key) + { + var basePath = Path.Combine(BasePath); + var langPath = Path.Combine(basePath, $"{Language}.dir"); + var files = Directory.GetFiles(langPath); + + foreach (var file in files) + { + if (!file.Contains(".cst")) + continue; + + var ids = Path.GetFileName(file); + var second = ids.IndexOf("_", 1, StringComparison.InvariantCultureIgnoreCase); + + if (second == -1) + continue; + + ids = ids.Substring(1, second - 1); + + if (ids != id.ToString()) + continue; + + var content = File.ReadAllText(file); + return CaretSeparatedText.Parse(content, key); + } + + return "***MISSING***"; + } + } +} diff --git a/changelog.md b/changelog.md index db502f8..469d05b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,8 +1,25 @@ # Change Log + +## 1.1.100 + +- Switched to Sixam.CST namespace and marked CSTNet namespace as obsolete. +- Performance improvements. +- Patch numbers are now in the triple digits. + +### UIText class + +The UIText class allows for travseing in ``//.dir`` directories and searching for CST files by their Id number. (e.g. _*154*_miscstrings.cst). By defualt, the base path is ``//uitext/.dir``. For more info, see [usage.md](./usage.md). + +## 1.0.3 + +- Backport switch to Sixam.CST namespace +- Internal improvements. + ## 1.0.2 - Fixed the multiple line parsing in the v2 format. - Replaced "``[ENTRY NOT FOUND]``" message with "``***MISSING***``". + ## 1.0.1 Despite only being a point release, this includes a major refinement to the normalizing algorithm. diff --git a/notebooks/cst.ipynb b/notebooks/cst.ipynb index 791ff97..1637710 100644 --- a/notebooks/cst.ipynb +++ b/notebooks/cst.ipynb @@ -29,7 +29,7 @@ "execution_count": 1, "metadata": {}, "source": [ - "public static class CST\n", + "public static class CaretSeparatedText\n", "{\n", " const char CARET = '^';\n", " static readonly string _lf = \"\\u000A\";\n", @@ -122,41 +122,64 @@ "execution_count": 1, "metadata": {}, "source": [ + "class ContentStrings\n", + "{\n", + " string Language { get; set; } = \"english\";\n", + "\n", + " public string GetText(string table, int key) => GetText(table, key.ToString());\n", + "\n", + " public string GetText(string table, string key)\n", + " {\n", + " var baseDir = Path.Combine(Environment.CurrentDirectory, \"data\", \"uitext\", $\"{Language}.dir\");\n", + " var files = Directory.GetFiles(baseDir);\n", + "\n", + " foreach (var file in files)\n", + " {\n", + " var id = Path.GetFileName(file);\n", + " var second = id.IndexOf(\"_\", 1);\n", + "\n", + " if (second == -1)\n", + " continue;\n", + "\n", + " id = id.Substring(1, second - 1);\n", + "\n", + " if (id != table)\n", + " continue;\n", + "\n", + " var content = File.ReadAllText(file);\n", + " return CaretSeparatedText.Parse(content, key);\n", + " }\n", + "\n", + " return \"***MISSING***\";\n", + " }\n", + "\n", + " public static string CSTFile(string cst, string key)\n", + " {\n", + " var path = Path.Combine(AppContext.BaseDirectory, cst);\n", + " var file = File.ReadAllText(path);\n", + "\n", + " return CaretSeparatedText.Parse(file, key);\n", + " }\n", + "}" + ], + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "source": [ + "var english = new ContentStrings();\n", "var v1Path = Path.Combine(Environment.CurrentDirectory, \"data\", \"v1.cst\");\n", "var v1File = File.ReadAllText(v1Path);\n", - "var one = CST.Parse(v1File, 1);\n", - "var three = CST.Parse(v1File, 3);\n", - "var four = CST.Parse(v1File, 4);\n", + "var one = english.GetText(\"102\", \"Singleline\");\n", + "/*var three = CaretSeparatedText.Parse(v1File, 3);\n", + "var four = CaretSeparatedText.Parse(v1File, 4); */\n", "Console.WriteLine($\"One:{Environment.NewLine}{one}\");\n", - "Console.WriteLine($\"Three:{Environment.NewLine}{three}\");\n", - "Console.WriteLine($\"Four:{Environment.NewLine}{four}\");" + "/*Console.WriteLine($\"Three:{Environment.NewLine}{three}\");\n", + "Console.WriteLine($\"Four:{Environment.NewLine}{four}\"); */" ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": "One:\r\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac dictum orci, at tincidunt nulla. Donec aliquet, %1 eros non interdum posuere, ipsum sapien molestie nunc, nec facilisis libero ipsum et risus. In sed lorem vel ipsum placerat viverra.\r\n" - }, - "execution_count": 1, - "metadata": {} - }, - { - "output_type": "execute_result", - "data": { - "text/plain": "Three:\r\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam venenatis ac odio ut pretium. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec semper turpis tempor, bibendum sapien at, blandit neque. Vivamus hendrerit imperdiet elit, vel sollicitudin nulla luctus vel. Vivamus nisl quam, feugiat a diam aliquam, iaculis vestibulum nunc. Maecenas euismod leo enim, faucibus ultrices ipsum semper eu. Praesent ullamcorper justo at maximus ultricies.\r\n" - }, - "execution_count": 1, - "metadata": {} - }, - { - "output_type": "execute_result", - "data": { - "text/plain": "Four:\r\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce justo dui, rhoncus a pulvinar sit amet, fermentum vitae lorem. Maecenas nec nisi sit amet eros rutrum congue. In sagittis suscipit arcu, ac vestibulum nunc feugiat volutpat.\r\n\r\nVivamus consequat velit dui, sit amet rhoncus dui malesuada a. Maecenas hendrerit commodo mi et scelerisque. Cras pharetra ultrices aliquam. Praesent ac efficitur magna, vitae scelerisque metus.\r\n" - }, - "execution_count": 1, - "metadata": {} - } - ] + "outputs": [] }, { "cell_type": "code", @@ -165,29 +188,12 @@ "source": [ "var v2Path = Path.Combine(Environment.CurrentDirectory, \"data\", \"v2.cst\");\n", "var v2File = File.ReadAllText(v2Path);\n", - "var singleLineV2 = CST.Parse(v2File, \"Singleline\");\n", - "var multiLineV2 = CST.Parse(v2File, \"Multiline\");\n", + "var singleLineV2 = CaretSeparatedText.Parse(v2File, \"Singleline\");\n", + "var multiLineV2 = CaretSeparatedText.Parse(v2File, \"Multiline\");\n", "Console.WriteLine($\"Single line v2:{Environment.NewLine}{singleLineV2}\");\n", "Console.WriteLine($\"Multiline v2:{Environment.NewLine}{multiLineV2}\");" ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": "Single line v2:\r\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ultricies nulla eu tortor mattis, dictum posuere lacus ornare. Maecenas a massa in ligula finibus luctus eu vitae nibh. Proin imperdiet dapibus mauris quis placerat.\r\n" - }, - "execution_count": 1, - "metadata": {} - }, - { - "output_type": "execute_result", - "data": { - "text/plain": "Multiline v2:\r\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc gravida nunc non justo pretium consectetur. Sed tempus libero ac ligula aliquam elementum. Duis vitae interdum leo. Sed semper nulla %1 a lectus dictum dictum.\r\n\r\nQuisque vehicula, nisi ut scelerisque sodales, nisi ipsum sodales ipsum, in rutrum tellus lacus sed nibh. Etiam mauris velit, elementum sed placerat et, elementum et tellus. Duis vitae elit fermentum, viverra lorem in, lobortis elit\r\n" - }, - "execution_count": 1, - "metadata": {} - } - ] + "outputs": [] } ], "metadata": { diff --git a/notebooks/data/uitext/english.dir/_101_v1.cst b/notebooks/data/uitext/english.dir/_101_v1.cst new file mode 100644 index 0000000..8b800ec --- /dev/null +++ b/notebooks/data/uitext/english.dir/_101_v1.cst @@ -0,0 +1,8 @@ +1 ^Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac dictum orci, at tincidunt nulla. Donec aliquet, %1 eros non interdum posuere, ipsum sapien molestie nunc, nec facilisis libero ipsum et risus. In sed lorem vel ipsum placerat viverra.^ +2 ^Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc pharetra nunc nec erat finibus efficitur. Duis non ullamcorper purus. Donec sit amet ultricies sapien. Sed lacinia sem eu nunc gravida, vitae tincidunt eros tempus. Quisque nibh est, tempus sit amet purus at, facilisis cursus ante. Nam nisi purus, vehicula sed magna ac, lobortis aliquam urna. Sed condimentum, felis a placerat tincidunt, est augue pulvinar turpis, eu dictum leo diam quis mi. Nulla non efficitur neque, sed efficitur orci. Aliquam quis libero consequat, convallis tortor sit amet, varius orci. + +Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc vel dictum eros, vitae mattis risus. Curabitur eget nisi interdum, euismod nisl in, fermentum turpis. Morbi a feugiat lacus. Duis ligula felis, commodo quis sodales ac, congue sit amet tortor. Sed vulputate, velit id interdum convallis, purus nisl interdum lorem, sit amet aliquam lacus sapien ac neque. Proin sit amet ultricies mi.^ +3 ^Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam venenatis ac odio ut pretium. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec semper turpis tempor, bibendum sapien at, blandit neque. Vivamus hendrerit imperdiet elit, vel sollicitudin nulla luctus vel. Vivamus nisl quam, feugiat a diam aliquam, iaculis vestibulum nunc. Maecenas euismod leo enim, faucibus ultrices ipsum semper eu. Praesent ullamcorper justo at maximus ultricies.^ +4^Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce justo dui, rhoncus a pulvinar sit amet, fermentum vitae lorem. Maecenas nec nisi sit amet eros rutrum congue. In sagittis suscipit arcu, ac vestibulum nunc feugiat volutpat. + +Vivamus consequat velit dui, sit amet rhoncus dui malesuada a. Maecenas hendrerit commodo mi et scelerisque. Cras pharetra ultrices aliquam. Praesent ac efficitur magna, vitae scelerisque metus.^ \ No newline at end of file diff --git a/CSTNet.Tests/v2.cst b/notebooks/data/uitext/english.dir/_102_v2.cst similarity index 100% rename from CSTNet.Tests/v2.cst rename to notebooks/data/uitext/english.dir/_102_v2.cst diff --git a/usage.md b/usage.md new file mode 100644 index 0000000..0c8cfdb --- /dev/null +++ b/usage.md @@ -0,0 +1,61 @@ +# Usage + +## Basic Parsing + +```text +1 ^The quick brown fox jumps over the lazy dog.^ +``` + +```csharp +#r "nuget:Sixam.CST,1.1" +using System; +using System.IO; +using Sixam.CST; + +var file = File.ReadAllText("example.cst"); +var example = CaretSeparatedText.Parse(file, 1); + +Console.WriteLine(example); +``` + +See working example on [.NET Fiddle](https://dotnetfiddle.net/ecKb2h). + +## Complex Scenarios + +In production, CST files were used in The Sims Online (TSO) to provide translations. It was required that they were prefixed with numbers enclosed in underscores, known as the ID. The IDs were used to locate the right file without knowing it's name. Meanwhile, each translation was split into their respective ``uitext/.dir`` directories: + +- ``uitext/english.dir/_154_miscstrings.cst`` +- ``uitext/swedish.dir/_154_miscstrings.cst``[^1] + +Starting with 1.1, the UIText class provides methods that directorly map to these directories relative to the application's. + +```csharp +#r "nuget:Sixam.CST,1.1" +using Sixam.CST; + +var english = new UIText(); // UIText assumes English +var swedish = new UIText("swedish"); +var engExample = english.GetText(101, 1); // english.dir/_101_example.cst +var sweExample = swedish.GetText(101, 1); // swedish.dir/_101_example.cst + +Console.WriteLine(engExample); +Console.WriteLine(sweExample); +``` + +Note that GetText() remains unchanged because the translation is expected to be same id and key, despite being in a different directory. + +### Changing base directories + +If you want to change the base directory, you can. Though, this is still a work in progress and not recommended. + +```csharp +#r "nuget:Sixam.CST,1.1" +using Sixam.CST; + +var example = new UIText() +{ + BasePath = new[] { "gamedata", "uitext" }, +}; +``` + +[^1]: TSO only supported English. \ No newline at end of file