diff --git a/README.md b/README.md index 52efaac..5432b0b 100644 --- a/README.md +++ b/README.md @@ -148,12 +148,15 @@ Didot utilizes some templating engines, which allow for powerful and flexible te The command to run Didot is simply `didot`. When executing it, you need to provide three required arguments: -- `-t, --Template`: Specifies the path to the Scriban template file. -- `-s, --Source`: Specifies the path to the source data file, which can be in YAML or JSON format. -- `-o, --Output`: Specifies the path to the output file where the generated content will be saved. If not specified the output is redirected to the console. +- `-t, --Template` (required): Specifies the path to the Scriban template file. +- `-s, --Source`: Specifies the path to the source data file, which can be in YAML, JSON, or XML format. If this argument is not provided, the data will be read from the console input. In such cases, the `-p, --Parser` option becomes mandatory. +- `-p, --Parser`: Defines the parser to use when the source data is provided through the console. Accepted values are `yaml`, `json` or `xml`. This option is required only when the --Source argument is omitted. +- `-o, --Output`: Specifies the path to the output file where the generated content will be saved. If not provided, the output will be displayed directly in the console. #### Example: +##### With a source file: + ```bash didot -t template.scriban -s data.yaml -o page.html ``` @@ -164,4 +167,16 @@ In this example: * `data.yaml` is the source file containing the structured data in YAML format. * `page.html` is the output file that will contain the generated content. +##### With data from the console: + +```bash +cat data.json | didot -t template.hbs -p json +``` + +In this example: + +* `template.hbs` is the Handlebars template file. +* `json` is the parser of input data. +* the output is redirected to the console. + Make sure that the template file and source file are correctly formatted and aligned with your data model to produce the desired result. diff --git a/src/Didot.Cli/Options.cs b/src/Didot.Cli/Options.cs index 64bb7a7..e609b64 100644 --- a/src/Didot.Cli/Options.cs +++ b/src/Didot.Cli/Options.cs @@ -11,9 +11,12 @@ public class Options [Option('t', "Template", Required = true, HelpText = "Path to the template file.")] public required string Template { get; set; } - [Option('s', "Source", Required = true, HelpText = "Path to the source file.")] - public required string Source { get; set; } + [Option('s', "Source", Required = false, HelpText = "Path to the source file.")] + public string? Source { get; set; } + + [Option('p', "Parser", Required = false, HelpText = "The parser to use when reading from StdIn.")] + public string? Parser { get; set; } [Option('o', "Output", Required = false, HelpText = "Path to the generated file.")] - public required string Output { get; set; } + public string? Output { get; set; } } diff --git a/src/Didot.Cli/Program.cs b/src/Didot.Cli/Program.cs index 603f989..634d203 100644 --- a/src/Didot.Cli/Program.cs +++ b/src/Didot.Cli/Program.cs @@ -1,8 +1,11 @@ using System; +using System.Text; using CommandLine; +using CommandLine.Text; using Didot.Core; using Didot.Core.SourceParsers; using Didot.Core.TemplateEngines; +using HandlebarsDotNet; namespace Didot.Cli; public class Program @@ -16,7 +19,27 @@ public static void Main(string[] args) static void RunWithOptions(Options opts) { - var sourceExtension = new FileInfo(opts.Source).Extension; + if (string.IsNullOrEmpty(opts.Source) && string.IsNullOrEmpty(opts.Parser)) + { + Console.WriteLine("Error: Missing input source. You must provide either the --parser option when reading from StdIn or the --source option for a file. At least one of these options is required."); + return; + } + + var sourceExtension = string.IsNullOrEmpty(opts.Source) + ? $".{opts.Parser!.ToLowerInvariant()}" + : new FileInfo(opts.Source).Extension; + + using var source = string.IsNullOrEmpty(opts.Source) + ? copyInStream() + : File.OpenRead(opts.Source); + + static Stream copyInStream() + { + string consoleInput = Console.In.ReadToEnd(); + byte[] inputBytes = Encoding.UTF8.GetBytes(consoleInput); + return new MemoryStream(inputBytes); + } + var parserFactory = new FileBasedSourceParserFactory(); var parser = parserFactory.GetSourceParser(sourceExtension); @@ -25,7 +48,6 @@ static void RunWithOptions(Options opts) var engine = engineFactory.GetTemplateEngine(templateExtension); var printer = new Printer(engine, parser); - using var source = File.OpenRead(opts.Source); using var template = File.OpenRead(opts.Template); var output = printer.Render(template, source); diff --git a/testing/Didot.Cli.Testing/ProgramTests.cs b/testing/Didot.Cli.Testing/ProgramTests.cs index 9fd8345..ceb2a73 100644 --- a/testing/Didot.Cli.Testing/ProgramTests.cs +++ b/testing/Didot.Cli.Testing/ProgramTests.cs @@ -43,10 +43,13 @@ public void CaptureConsoleOutputTest( [ValueSource(nameof(Templates))] string engine, [ValueSource(nameof(DataSets))] string data) { + using var source = new StreamReader(Path.Combine("data", $"data-01.{data}")); + Console.SetIn(source); + var args = new string[] { - $"-ttemplate/template-01.{engine}", - $"-sdata/data-01.{data}" + $"-ttemplate/template-01.{engine}", + $"-p{data}" }; Program.Main(args); @@ -54,7 +57,7 @@ public void CaptureConsoleOutputTest( using (var reader = new StreamReader(MemoryStream)) { var consoleOutput = reader.ReadToEnd().Standardize(); - var expected = File.ReadAllText($"Expectation/expectation-01.txt").Standardize(); + var expected = File.ReadAllText(Path.Combine("Expectation", $"expectation-01.txt")).Standardize(); Assert.That(consoleOutput, Is.EqualTo(expected)); } }