diff --git a/src/dotnet/Taml.sln b/src/dotnet/Taml.sln index 26150ae..ebb172a 100644 --- a/src/dotnet/Taml.sln +++ b/src/dotnet/Taml.sln @@ -21,6 +21,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test.Taml.Configuration", " EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Taml.Configuration", "Taml.Configuration", "{D8BF9D98-AE40-4736-B471-1A0CD71184C7}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Yaml.Writer.Taml", "Yaml.Writer.Taml", "{B52120A4-96ED-42B3-8504-69D315916E5F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yaml.Writer.Taml", "Yaml.Writer.Taml\Yaml.Writer.Taml\Yaml.Writer.Taml.csproj", "{80257695-D4DF-4CFB-BCAF-0B9AA559064B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test.Yaml.Writer.Taml", "Yaml.Writer.Taml\Test.Yaml.Writer.Taml\Test.Yaml.Writer.Taml.csproj", "{6A469558-7825-4D6B-8A19-758C6C2A7C9E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yaml.Writer.Cli", "Yaml.Writer.Taml\Yaml.Writer.Cli\Yaml.Writer.Cli.csproj", "{20A28BFB-F449-4EB8-9DF2-5732CEC3213C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -79,6 +87,42 @@ Global {2CF41FAB-4607-4772-8544-8D2EF8FF9DB8}.Release|x64.Build.0 = Release|Any CPU {2CF41FAB-4607-4772-8544-8D2EF8FF9DB8}.Release|x86.ActiveCfg = Release|Any CPU {2CF41FAB-4607-4772-8544-8D2EF8FF9DB8}.Release|x86.Build.0 = Release|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Debug|x64.ActiveCfg = Debug|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Debug|x64.Build.0 = Debug|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Debug|x86.ActiveCfg = Debug|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Debug|x86.Build.0 = Debug|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Release|Any CPU.Build.0 = Release|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Release|x64.ActiveCfg = Release|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Release|x64.Build.0 = Release|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Release|x86.ActiveCfg = Release|Any CPU + {80257695-D4DF-4CFB-BCAF-0B9AA559064B}.Release|x86.Build.0 = Release|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Debug|x64.ActiveCfg = Debug|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Debug|x64.Build.0 = Debug|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Debug|x86.ActiveCfg = Debug|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Debug|x86.Build.0 = Debug|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Release|Any CPU.Build.0 = Release|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Release|x64.ActiveCfg = Release|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Release|x64.Build.0 = Release|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Release|x86.ActiveCfg = Release|Any CPU + {6A469558-7825-4D6B-8A19-758C6C2A7C9E}.Release|x86.Build.0 = Release|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Debug|x64.ActiveCfg = Debug|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Debug|x64.Build.0 = Debug|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Debug|x86.ActiveCfg = Debug|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Debug|x86.Build.0 = Debug|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Release|Any CPU.Build.0 = Release|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Release|x64.ActiveCfg = Release|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Release|x64.Build.0 = Release|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Release|x86.ActiveCfg = Release|Any CPU + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -86,6 +130,9 @@ Global GlobalSection(NestedProjects) = preSolution {069403C6-DE0A-4043-8D92-88DADE3DB3E2} = {D8BF9D98-AE40-4736-B471-1A0CD71184C7} {2CF41FAB-4607-4772-8544-8D2EF8FF9DB8} = {D8BF9D98-AE40-4736-B471-1A0CD71184C7} + {80257695-D4DF-4CFB-BCAF-0B9AA559064B} = {B52120A4-96ED-42B3-8504-69D315916E5F} + {6A469558-7825-4D6B-8A19-758C6C2A7C9E} = {B52120A4-96ED-42B3-8504-69D315916E5F} + {20A28BFB-F449-4EB8-9DF2-5732CEC3213C} = {B52120A4-96ED-42B3-8504-69D315916E5F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {407D8799-35B4-4DDC-A878-538CAC2A5CE5} diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenChildArrays/WhenWriterGivesYaml.cs b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenChildArrays/WhenWriterGivesYaml.cs new file mode 100644 index 0000000..e1c11d6 --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenChildArrays/WhenWriterGivesYaml.cs @@ -0,0 +1,24 @@ +using System; +using TAML; +using TAML.Writer.Yaml; +using Test.Taml; +using Xunit; + +namespace Test.Yaml.Writer.Taml.NET.GivenChildArrays +{ + public class WhenWriterGivesYaml : BaseFixture + { + protected override string SampleFilename => "GivenChildArrays/childarrays.taml"; + + [Fact] + public void ShouldFindThreeElements() + { + var tamlDocument = Parser.Parse(base.Sample); + var yamlString = YamlWriter.Write(tamlDocument); + + var newLines = yamlString.Split(Environment.NewLine); + + Assert.Equal(13, newLines.Length); + } + } +} diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenChildArrays/childarrays.taml b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenChildArrays/childarrays.taml new file mode 100644 index 0000000..6e1366e --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenChildArrays/childarrays.taml @@ -0,0 +1,12 @@ +value1 + value12 + value13 + value14 +value2 + value22 + value23 + value24 +value3 + value32 + value33 + value34 diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/WhenParsingSampleOne.cs b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/WhenParsingSampleOne.cs new file mode 100644 index 0000000..9441034 --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/WhenParsingSampleOne.cs @@ -0,0 +1,50 @@ +using System; +using TAML; +using TAML.Writer.Yaml; +using Test.Taml; +using Xunit; + +namespace Test.Yaml.Writer.Taml.NET.GivenComplexChildDocument +{ + public class WhenParsingSampleOne : BaseFixture + { + protected override string SampleFilename => "GivenComplexChildDocument/sample1.taml"; + + [Fact] + public void ShouldHaveOneRootKey() + { + var result = YamlWriter.Write(Parser.Parse(base.Sample)); + + var rootLineCount = 0; + + foreach (var line in result.Split(Environment.NewLine)) + { + if (!line.StartsWith(" ") && line.Length > 2) rootLineCount++; + } + + Assert.Equal(1, rootLineCount); + } + + [Fact] + public void ShouldHaveCorrectNesting() + { + var expected = +@"root: + - key1: value1 + - key2: value2 + - key3: + - item1 + - item2 + - item3 + - item4: + - key41: value41 + - key42: value42 + - key43: value43 + - key44: value44 +"; + var result = YamlWriter.Write(Parser.Parse(base.Sample)); + + Assert.Equal(expected, result); + } + } +} diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/sample1.taml b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/sample1.taml new file mode 100644 index 0000000..c7a4b36 --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/sample1.taml @@ -0,0 +1,12 @@ +root + key1 value1 + key2 value2 + key3 + item1 + item2 + item3 + item4 + key41 value41 + key42 value42 + key43 value43 + key44 value44 diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/sample2.taml b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/sample2.taml new file mode 100644 index 0000000..f67396b --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenComplexChildDocument/sample2.taml @@ -0,0 +1,12 @@ +root1 + key1 value1 + key2 value2 + key3 + item1 + item2 + key4 value4 +root2 + key41 value41 + key42 value42 + key43 value43 + key44 value44 diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenSimpleArray/WhenWritingYaml.cs b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenSimpleArray/WhenWritingYaml.cs new file mode 100644 index 0000000..5b0592a --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenSimpleArray/WhenWritingYaml.cs @@ -0,0 +1,25 @@ +using System; +using Xunit; +using Test.Taml; +using TAML; +using TAML.Writer.Yaml; + +namespace Test.Yaml.Writer.Taml.NET.GivenSimpleArray +{ + public class WhenWritingYaml : BaseFixture + { + protected override string SampleFilename => "GivenSimpleArray/simple.taml"; + + [Fact] + public void ThenShouldFindArray() + { + var tamlDocument = Parser.Parse(Sample); + + var yamlString = YamlWriter.Write(tamlDocument); + + var newLines = yamlString.Split(Environment.NewLine); + + Assert.Equal(5, newLines.Length); + } + } +} diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenSimpleArray/simple.taml b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenSimpleArray/simple.taml new file mode 100644 index 0000000..6075f39 --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/GivenSimpleArray/simple.taml @@ -0,0 +1,4 @@ +key + value1 + value2 + value3 diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Spec_1-1/GivenComments/WhenReadingComments.cs b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Spec_1-1/GivenComments/WhenReadingComments.cs new file mode 100644 index 0000000..d34a858 --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Spec_1-1/GivenComments/WhenReadingComments.cs @@ -0,0 +1,27 @@ +using TAML; +using TAML.Writer.Yaml; +using Test.Taml; +using Xunit; + +namespace Test.Yaml.Writer.Taml.NET.Spec_1_1.GivenComments +{ + public class WhenReadingComments : BaseFixture + { + protected override string SampleFilename => "Spec_1-1/GivenComments/simple.taml"; + + [Fact] + public void ThenShouldIgnoreCommentLines() + { + // arrange + var expected = @"key1: value1 +key2: value2 +"; + + // act + var result = YamlWriter.Write(Parser.Parse(Sample)); + + // assert + Assert.Equal(expected, result); + } + } +} diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Spec_1-1/GivenComments/simple.taml b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Spec_1-1/GivenComments/simple.taml new file mode 100644 index 0000000..29b9822 --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Spec_1-1/GivenComments/simple.taml @@ -0,0 +1,3 @@ +key1 value1 +# This is a comment +key2 value2 diff --git a/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Test.Yaml.Writer.Taml.csproj b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Test.Yaml.Writer.Taml.csproj new file mode 100644 index 0000000..0bcb3dd --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Test.Yaml.Writer.Taml/Test.Yaml.Writer.Taml.csproj @@ -0,0 +1,44 @@ + + + + netcoreapp3.1 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + Always + + + + diff --git a/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/Program.cs b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/Program.cs new file mode 100644 index 0000000..b3f182e --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/Program.cs @@ -0,0 +1,37 @@ +using System; +using System.IO; +using TAML; +using TAML.Writer.Yaml; + +namespace Yaml.Writer.Cli +{ + internal class Program + { + private static void Main(string[] args) + { + var filename = GetFileName(args); + Console.WriteLine($"Read file: {filename}"); + var tamlDoc = Parser.Parse(new StreamReader(File.OpenRead(filename))); + + var yaml = YamlWriter.Write(tamlDoc); + + Console.WriteLine(yaml); + } + + /// + /// Find the first file with a `.taml` extension from the command line arguments. + /// If no such file exists then default to `sample1.taml` + /// + private static string GetFileName(string[] args) + { + foreach(var arg in args){ + + if (arg.EndsWith("taml") && File.Exists(arg)) + { + return arg; + } + } + return "sample1.taml"; + } + } +} diff --git a/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/Yaml.Writer.Cli.csproj b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/Yaml.Writer.Cli.csproj new file mode 100644 index 0000000..b4b3e9f --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/Yaml.Writer.Cli.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + diff --git a/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/sample1.taml b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/sample1.taml new file mode 100644 index 0000000..971ac7f --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/sample1.taml @@ -0,0 +1,12 @@ +root + key1 value1 + key2 value2 + key3 + item1 + item2 + item3 + item4 + key41 value41 + key42 value42 + key43 value43 + key44 value44 \ No newline at end of file diff --git a/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/sample2.taml b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/sample2.taml new file mode 100644 index 0000000..f67396b --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Cli/sample2.taml @@ -0,0 +1,12 @@ +root1 + key1 value1 + key2 value2 + key3 + item1 + item2 + key4 value4 +root2 + key41 value41 + key42 value42 + key43 value43 + key44 value44 diff --git a/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Taml/Yaml.Writer.Taml.csproj b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Taml/Yaml.Writer.Taml.csproj new file mode 100644 index 0000000..00fa1eb --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Taml/Yaml.Writer.Taml.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.0 + 0.0.1 + Jeffrey T. Fritz and Friends + Yaml writer for TAML + Copyright Jeffery T. Fritz + MIT + https://github.com/csharpfritz/TAML + https://github.com/cgleadall/TAML + GitHub + TAML.Writer.Yaml + + + + + + + diff --git a/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Taml/YamlWriter.cs b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Taml/YamlWriter.cs new file mode 100644 index 0000000..413c383 --- /dev/null +++ b/src/dotnet/Yaml.Writer.Taml/Yaml.Writer.Taml/YamlWriter.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TAML.Writer.Yaml +{ + public class YamlWriter + { + /// + /// Convert the provided `tamlDocument` to a Yaml string. + /// + public static string Write(TamlDocument tamlDocument) + { + var yaml = new StringBuilder(); + var indentCount = 0; + + foreach (var item in tamlDocument.KeyValuePairs) + { + if (item.HasValue && item.Value != null) + { + WriteKeyWithTamlValue(indentCount, item, yaml); + } + } + + return yaml.ToString(); + } + + /// Create an 'indentation string that contains `indentCount` spaces. + /// If the indentCount is grater than 0 then append the YAML 'Block Sequence' character + private static string Indent(int indentCount) + { + return "".PadLeft(indentCount) + (indentCount > 0 ? "- " : ""); + } + + /// Write a TamlKeyValuePair to the StringBuilder. + /// If the value is both a TamlValue and TamlArray then write only the "Key" with YAML 'Mapping Key'. + /// Then either: + /// a) a TamlArray, then write each TamlKeyValuePair recursively + /// b) a TamlValue, then write the Key and Value + /// c) neither, then simply write the Key + private static void WriteKeyWithTamlValue(int indentCount, TamlKeyValuePair tamlKvp, StringBuilder stringBuilder) + { + var isTamlValue = tamlKvp.Value is TamlValue; + var isTamlArray = tamlKvp.Value is TamlArray; + + if (isTamlArray && isTamlValue) + { + stringBuilder.AppendLine($"{Indent(indentCount)}{tamlKvp.Key}:"); + } + + if (isTamlArray && tamlKvp.HasValue && tamlKvp.Value != null) + { + var tva = (TamlArray)tamlKvp.Value; + foreach (var item in tva) + { + WriteKeyWithTamlValue(indentCount + 2, (TamlKeyValuePair)item, stringBuilder); + } + } + else if (isTamlValue) + { + stringBuilder.AppendLine($"{Indent(indentCount)}{tamlKvp.Key}: {tamlKvp.Value}"); + } + else + { + stringBuilder.AppendLine($"{Indent(indentCount)}{tamlKvp.Key}"); + } + } + } +}