RSCG – docopt.net
| name | docopt.net |
| nuget | https://www.nuget.org/packages/docopt.net/ |
| link | https://github.com/docopt/docopt.net |
| author | Atif Aziz |
Generating command line argument parsers from usage documentation.
This is how you can use docopt.net .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="docopt.net" Version="0.8.1" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
The code that you will use is
//Console.WriteLine(ConsoleArgs.ProgramArguments.Help); Console.WriteLine(ConsoleArgs.ProgramArguments.Usage);
Array 2 Any Usage: array_2_any.exe translate <text> array_2_any.exe translatefile <nameFile> array_2_any.exe (-h | --help) array_2_any.exe --version Options: -h --help Show this screen. --version Show version. --verbose Show more output.
The code that is generated is
#nullable enable annotations
using System.Collections;
using System.Collections.Generic;
using DocoptNet;
using DocoptNet.Internals;
using Leaves = DocoptNet.Internals.ReadOnlyList<DocoptNet.Internals.LeafPattern>;
namespace ConsoleArgs
{
partial class ProgramArguments : IEnumerable<KeyValuePair<string, object?>>
{
public const string Help = @"Array 2 Any
Usage:
array_2_any.exe translate <text>
array_2_any.exe translatefile <nameFile>
array_2_any.exe (-h | --help)
array_2_any.exe --version
Options:
-h --help Show this screen.
--version Show version.
--verbose Show more output.";
public const string Usage = @"Usage:
array_2_any.exe translate <text>
array_2_any.exe translatefile <nameFile>
array_2_any.exe (-h | --help)
array_2_any.exe --version";
static readonly IHelpFeaturingParser<ProgramArguments> Parser = GeneratedSourceModule.CreateParser(Help, Parse).EnableHelp();
public static IHelpFeaturingParser<ProgramArguments> CreateParser() => Parser;
static IParser<ProgramArguments>.IResult Parse(IEnumerable<string> args, ParseFlags flags, string? version)
{
var options = new List<Option>
{
new("-h", "--help", 0, false),
new(null, "--version", 0, false),
new(null, "--verbose", 0, false),
};
return GeneratedSourceModule.Parse(Help, Usage, args, options, flags, version, Parse);
static IParser<ProgramArguments>.IResult Parse(Leaves left)
{
var required = new RequiredMatcher(1, left, new Leaves());
Match(ref required);
if (!required.Result || required.Left.Count > 0)
{
return GeneratedSourceModule.CreateInputErrorResult<ProgramArguments>(string.Empty, Usage);
}
var collected = required.Collected;
var result = new ProgramArguments();
foreach (var leaf in collected)
{
var value = leaf.Value is { IsStringList: true } ? ((StringList)leaf.Value).Reverse() : leaf.Value;
switch (leaf.Name)
{
case "translate": result.CmdTranslate = (bool)value; break;
case "<text>": result.ArgText = (string?)value; break;
case "translatefile": result.CmdTranslatefile = (bool)value; break;
case "<nameFile>": result.ArgNamefile = (string?)value; break;
case "--help": result.OptHelp = (bool)value; break;
case "--version": result.OptVersion = (bool)value; break;
}
}
return GeneratedSourceModule.CreateArgumentsResult(result);
}
static void Match(ref RequiredMatcher required)
{
// Required(Either(Required(Command(translate, False), Argument(<text>, )), Required(Command(translatefile, False), Argument(<nameFile>, )), Required(Required(Option(-h,--help,0,False))), Required(Option(,--version,0,False))))
var a = new RequiredMatcher(1, required.Left, required.Collected);
while (a.Next())
{
// Either(Required(Command(translate, False), Argument(<text>, )), Required(Command(translatefile, False), Argument(<nameFile>, )), Required(Required(Option(-h,--help,0,False))), Required(Option(,--version,0,False)))
var b = new EitherMatcher(4, a.Left, a.Collected);
while (b.Next())
{
switch (b.Index)
{
case 0:
{
// Required(Command(translate, False), Argument(<text>, ))
var c = new RequiredMatcher(2, b.Left, b.Collected);
while (c.Next())
{
switch (c.Index)
{
case 0:
{
// Command(translate, False)
c.Match(PatternMatcher.MatchCommand, "translate", ArgValueKind.Boolean);
}
break;
case 1:
{
// Argument(<text>, )
c.Match(PatternMatcher.MatchArgument, "<text>", ArgValueKind.None);
}
break;
}
if (!c.LastMatched)
{
break;
}
}
b.Fold(c.Result);
}
break;
case 1:
{
// Required(Command(translatefile, False), Argument(<nameFile>, ))
var c = new RequiredMatcher(2, b.Left, b.Collected);
while (c.Next())
{
switch (c.Index)
{
case 0:
{
// Command(translatefile, False)
c.Match(PatternMatcher.MatchCommand, "translatefile", ArgValueKind.Boolean);
}
break;
case 1:
{
// Argument(<nameFile>, )
c.Match(PatternMatcher.MatchArgument, "<nameFile>", ArgValueKind.None);
}
break;
}
if (!c.LastMatched)
{
break;
}
}
b.Fold(c.Result);
}
break;
case 2:
{
// Required(Required(Option(-h,--help,0,False)))
var c = new RequiredMatcher(1, b.Left, b.Collected);
while (c.Next())
{
// Required(Option(-h,--help,0,False))
var d = new RequiredMatcher(1, c.Left, c.Collected);
while (d.Next())
{
// Option(-h,--help,0,False)
d.Match(PatternMatcher.MatchOption, "--help", ArgValueKind.Boolean);
if (!d.LastMatched)
{
break;
}
}
c.Fold(d.Result);
if (!c.LastMatched)
{
break;
}
}
b.Fold(c.Result);
}
break;
case 3:
{
// Required(Option(,--version,0,False))
var c = new RequiredMatcher(1, b.Left, b.Collected);
while (c.Next())
{
// Option(,--version,0,False)
c.Match(PatternMatcher.MatchOption, "--version", ArgValueKind.Boolean);
if (!c.LastMatched)
{
break;
}
}
b.Fold(c.Result);
}
break;
}
if (!b.LastMatched)
{
break;
}
}
a.Fold(b.Result);
if (!a.LastMatched)
{
break;
}
}
required.Fold(a.Result);
}
}
IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
{
yield return KeyValuePair.Create("translate", (object?)CmdTranslate);
yield return KeyValuePair.Create("<text>", (object?)ArgText);
yield return KeyValuePair.Create("translatefile", (object?)CmdTranslatefile);
yield return KeyValuePair.Create("<nameFile>", (object?)ArgNamefile);
yield return KeyValuePair.Create("--help", (object?)OptHelp);
yield return KeyValuePair.Create("--version", (object?)OptVersion);
}
IEnumerator<KeyValuePair<string, object?>> IEnumerable<KeyValuePair<string, object?>>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
/// <summary><c>Command(translate, False)</c></summary>
public bool CmdTranslate { get; private set; }
/// <summary><c>Argument(<text>, )</c></summary>
public string? ArgText { get; private set; }
/// <summary><c>Command(translatefile, False)</c></summary>
public bool CmdTranslatefile { get; private set; }
/// <summary><c>Argument(<nameFile>, )</c></summary>
public string? ArgNamefile { get; private set; }
/// <summary><c>Option(-h,--help,0,False)</c></summary>
public bool OptHelp { get; private set; }
/// <summary><c>Option(,--version,0,False)</c></summary>
public bool OptVersion { get; private set; }
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/docopt.net