mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 02:25:28 +08:00 
			
		
		
		
	Add AsciiCast demos for docs
This commit is contained in:
		
				
					committed by
					
						
						Patrik Svensson
					
				
			
			
				
	
			
			
			
						parent
						
							69fdae70c0
						
					
				
				
					commit
					46abadaccb
				
			
							
								
								
									
										13
									
								
								resources/scripts/Generate-Samples.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								resources/scripts/Generate-Samples.ps1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
# first arg is either the name of a single sample you want to run or leave
 | 
			
		||||
# blank if you want to run them all. the samples aren't going to run at the same
 | 
			
		||||
# speed each time so if you run all of them you'll have everything as a change
 | 
			
		||||
# for your commit so use this sparingly.
 | 
			
		||||
 | 
			
		||||
# Generate the files
 | 
			
		||||
Push-Location Generator
 | 
			
		||||
dotnet run -- samples -o "../../../docs/input/assets/casts" $args[0]
 | 
			
		||||
if(!$?) {
 | 
			
		||||
    Pop-Location
 | 
			
		||||
    Throw "An error occured when generating code."
 | 
			
		||||
}
 | 
			
		||||
Pop-Location
 | 
			
		||||
							
								
								
									
										104
									
								
								resources/scripts/Generator/Commands/AsciiCastOut.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								resources/scripts/Generator/Commands/AsciiCastOut.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.Json;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands
 | 
			
		||||
{
 | 
			
		||||
    public class AsciiCastOut : IAnsiConsoleOutput
 | 
			
		||||
    {
 | 
			
		||||
        private sealed class AsciiCastWriter : TextWriter
 | 
			
		||||
        {
 | 
			
		||||
            private readonly TextWriter _wrappedTextWriter;
 | 
			
		||||
            private readonly StringBuilder _builder = new();
 | 
			
		||||
            private int? _firstTick;
 | 
			
		||||
 | 
			
		||||
            public AsciiCastWriter(TextWriter wrappedTextWriter)
 | 
			
		||||
            {
 | 
			
		||||
                _wrappedTextWriter = wrappedTextWriter;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override void Write(string value)
 | 
			
		||||
            {
 | 
			
		||||
                if (value == null)
 | 
			
		||||
                {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Append(value);
 | 
			
		||||
                _wrappedTextWriter.Write(value);
 | 
			
		||||
                base.Write(value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override Encoding Encoding => _wrappedTextWriter.Encoding;
 | 
			
		||||
 | 
			
		||||
            private void Append(string value)
 | 
			
		||||
            {
 | 
			
		||||
                var tick = 0m;
 | 
			
		||||
                if (_firstTick.HasValue)
 | 
			
		||||
                {
 | 
			
		||||
                    tick = Environment.TickCount - _firstTick.Value;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    _firstTick = Environment.TickCount;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                tick /= 1000m;
 | 
			
		||||
 | 
			
		||||
                _builder.Append('[').Append(tick).Append(", \"o\", \"").Append(JsonEncodedText.Encode(value)).AppendLine("\"]");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public string GetJsonAndClearBuffer()
 | 
			
		||||
            {
 | 
			
		||||
                var json = _builder.ToString();
 | 
			
		||||
 | 
			
		||||
                // reset the buffer and also reset the first tick count
 | 
			
		||||
                _builder.Clear();
 | 
			
		||||
                _firstTick = null;
 | 
			
		||||
                return json;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private readonly IAnsiConsoleOutput _wrappedAnsiConsole;
 | 
			
		||||
        private readonly AsciiCastWriter _asciiCastWriter;
 | 
			
		||||
 | 
			
		||||
        public AsciiCastOut(IAnsiConsoleOutput wrappedAnsiConsole)
 | 
			
		||||
        {
 | 
			
		||||
            _wrappedAnsiConsole = wrappedAnsiConsole;
 | 
			
		||||
            _asciiCastWriter = new AsciiCastWriter(_wrappedAnsiConsole.Writer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TextWriter Writer => _asciiCastWriter;
 | 
			
		||||
 | 
			
		||||
        public bool IsTerminal => _wrappedAnsiConsole.IsTerminal;
 | 
			
		||||
 | 
			
		||||
        public int Width => _wrappedAnsiConsole.Width;
 | 
			
		||||
 | 
			
		||||
        public int Height => _wrappedAnsiConsole.Height;
 | 
			
		||||
 | 
			
		||||
        public void SetEncoding(Encoding encoding)
 | 
			
		||||
        {
 | 
			
		||||
            _wrappedAnsiConsole.SetEncoding(encoding);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string GetCastJson(string title, int? width = null, int? height = null)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            var header = $"{{\"version\": 2, \"width\": {width ?? _wrappedAnsiConsole.Width}, \"height\": {height ?? _wrappedAnsiConsole.Height}, \"title\": \"{JsonEncodedText.Encode(title)}\", \"env\": {{\"TERM\": \"Spectre.Console\"}}}}";
 | 
			
		||||
            return $"{header}{Environment.NewLine}{_asciiCastWriter.GetJsonAndClearBuffer()}{Environment.NewLine}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class AsciiCastExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static AsciiCastOut WrapWithAsciiCastRecorder(this IAnsiConsole ansiConsole)
 | 
			
		||||
        {
 | 
			
		||||
            AsciiCastOut castRecorder = new(ansiConsole.Profile.Out);
 | 
			
		||||
            ansiConsole.Profile.Out = castRecorder;
 | 
			
		||||
 | 
			
		||||
            return castRecorder;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,7 +2,7 @@ using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using Generator.Models;
 | 
			
		||||
using Scriban;
 | 
			
		||||
using Spectre.Cli;
 | 
			
		||||
using Spectre.Console.Cli;
 | 
			
		||||
using Spectre.IO;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										62
									
								
								resources/scripts/Generator/Commands/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								resources/scripts/Generator/Commands/ConsoleExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using WindowsInput;
 | 
			
		||||
using WindowsInput.Native;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace DocExampleGenerator
 | 
			
		||||
{
 | 
			
		||||
    internal static class ConsoleExtensions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Displays something via AnsiConsole, waits a bit and then simulates typing based on the input. If the console
 | 
			
		||||
        /// doesn't have the focus this will just type into whatever window does so watch the alt-tab.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="console"></param>
 | 
			
		||||
        /// <param name="action">The display action.</param>
 | 
			
		||||
        /// <param name="input">The characters to type. ↑ for an up arrow, ↓ for down arrow, ↲ for a return and ¦ for a pause.</param>
 | 
			
		||||
        /// <param name="initialDelayMs">How long to delay before typing. This should be at least 100ms because we won't check if the prompt has displayed before simulating typing.</param>
 | 
			
		||||
        /// <param name="keypressDelayMs">Delay between keypresses. There will be a bit of randomness between each keypress +/- 20% of this value.</param>
 | 
			
		||||
        public static void DisplayThenType(this IAnsiConsole console, Action<IAnsiConsole> action, string input, int initialDelayMs = 500, int keypressDelayMs = 200)
 | 
			
		||||
        {
 | 
			
		||||
            if (initialDelayMs < 100)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentOutOfRangeException(nameof(initialDelayMs), "Initial delay must be greater than 100");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var random = new Random(Environment.TickCount);
 | 
			
		||||
            var inputTask = Task.Run(() => action(console));
 | 
			
		||||
            var typingTask = Task.Run(async () =>
 | 
			
		||||
            {
 | 
			
		||||
                await Task.Delay(initialDelayMs);
 | 
			
		||||
                var inputSimulator = new InputSimulator();
 | 
			
		||||
                foreach (var character in input)
 | 
			
		||||
                {
 | 
			
		||||
                    switch (character)
 | 
			
		||||
                    {
 | 
			
		||||
                        case '↑':
 | 
			
		||||
                            inputSimulator.Keyboard.KeyPress(VirtualKeyCode.UP);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case '↓':
 | 
			
		||||
                            inputSimulator.Keyboard.KeyPress(VirtualKeyCode.DOWN);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case '↲':
 | 
			
		||||
                            inputSimulator.Keyboard.KeyPress(VirtualKeyCode.RETURN);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case '¦':
 | 
			
		||||
                            await Task.Delay(keypressDelayMs + random.Next((int) (keypressDelayMs * -.2), (int) (keypressDelayMs * .2)));
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            inputSimulator.Keyboard.TextEntry(character);
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    await Task.Delay(keypressDelayMs + random.Next((int) (keypressDelayMs * -.2), (int) (keypressDelayMs * .2)));
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            Task.WaitAll(inputTask, typingTask);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -8,7 +8,7 @@ using AngleSharp.Html.Parser;
 | 
			
		||||
using Generator.Models;
 | 
			
		||||
using Scriban;
 | 
			
		||||
using Scriban.Runtime;
 | 
			
		||||
using Spectre.Cli;
 | 
			
		||||
using Spectre.Console.Cli;
 | 
			
		||||
using Spectre.IO;
 | 
			
		||||
using Path = Spectre.IO.Path;
 | 
			
		||||
using SpectreEnvironment = Spectre.IO.Environment;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
using Spectre.Cli;
 | 
			
		||||
using Spectre.Console.Cli;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										88
									
								
								resources/scripts/Generator/Commands/SampleCommand.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								resources/scripts/Generator/Commands/SampleCommand.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Generator.Commands.Samples;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
using Spectre.Console.Cli;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands
 | 
			
		||||
{
 | 
			
		||||
    internal class SampleCommand : Command<SampleCommand.Settings>
 | 
			
		||||
    {
 | 
			
		||||
        public class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            public Settings(string outputPath, string sample)
 | 
			
		||||
            {
 | 
			
		||||
                Sample = sample;
 | 
			
		||||
                OutputPath = outputPath ?? Environment.CurrentDirectory;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [CommandArgument(0, "[sample]")]
 | 
			
		||||
            public string Sample { get; }
 | 
			
		||||
 | 
			
		||||
            [CommandOption("-o|--output")]
 | 
			
		||||
            public string OutputPath { get; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private readonly IAnsiConsole _console;
 | 
			
		||||
 | 
			
		||||
        public SampleCommand(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            this._console = console;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings)
 | 
			
		||||
        {
 | 
			
		||||
            _console.Prompt(new ConfirmationPrompt("Some commands will mimic user input. Make sure this window has focus and press y"));
 | 
			
		||||
 | 
			
		||||
            var samples = typeof(BaseSample).Assembly
 | 
			
		||||
                .GetTypes()
 | 
			
		||||
                .Where(i => i.IsClass && i.IsAbstract == false && i.IsSubclassOf(typeof(BaseSample)))
 | 
			
		||||
                .Select(Activator.CreateInstance)
 | 
			
		||||
                .Cast<BaseSample>();
 | 
			
		||||
 | 
			
		||||
            if (!string.IsNullOrWhiteSpace(settings.Sample))
 | 
			
		||||
            {
 | 
			
		||||
                var desiredSample = samples.FirstOrDefault(i => i.Name().Equals(settings.Sample));
 | 
			
		||||
                if (desiredSample == null)
 | 
			
		||||
                {
 | 
			
		||||
                    _console.MarkupLine($"[red]Error:[/] could not find sample [blue]{settings.Sample}[/]");
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                samples = new List<BaseSample> { desiredSample};
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // from here on out everything we write will be recorded.
 | 
			
		||||
            var recorder = _console.WrapWithAsciiCastRecorder();
 | 
			
		||||
 | 
			
		||||
            foreach (var sample in samples)
 | 
			
		||||
            {
 | 
			
		||||
                var sampleName = sample.Name();
 | 
			
		||||
 | 
			
		||||
                var originalWidth = _console.Profile.Width;
 | 
			
		||||
                var originalHeight = _console.Profile.Height;
 | 
			
		||||
 | 
			
		||||
                _console.Profile.Encoding = Encoding.UTF8;
 | 
			
		||||
                _console.Profile.Width = sample.ConsoleSize.Cols;
 | 
			
		||||
                _console.Profile.Height = sample.ConsoleSize.Rows;
 | 
			
		||||
 | 
			
		||||
                foreach (var (capabilityName, action) in sample.GetCapabilities())
 | 
			
		||||
                {
 | 
			
		||||
                    action(_console.Profile.Capabilities);
 | 
			
		||||
                    sample.Run(_console);
 | 
			
		||||
                    var json = recorder.GetCastJson($"{sampleName} ({capabilityName})", sample.ConsoleSize.Cols + 2, sample.ConsoleSize.Rows);
 | 
			
		||||
                    File.WriteAllText(Path.Combine(settings.OutputPath, $"{sampleName}-{capabilityName}.cast"), json);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                _console.Profile.Width = originalWidth;
 | 
			
		||||
                _console.Profile.Height = originalHeight;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class BarChartSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (base.ConsoleSize.Cols, 5);
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.Write(new BarChart()
 | 
			
		||||
                .Width(60)
 | 
			
		||||
                .Label("[green bold underline]Number of fruits[/]")
 | 
			
		||||
                .CenterLabel()
 | 
			
		||||
                .AddItem("Apple", 12, Color.Yellow)
 | 
			
		||||
                .AddItem("Orange", 54, Color.Green)
 | 
			
		||||
                .AddItem("Banana", 33, Color.Red));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								resources/scripts/Generator/Commands/Samples/BaseSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								resources/scripts/Generator/Commands/Samples/BaseSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    public abstract class BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public abstract void Run(IAnsiConsole console);
 | 
			
		||||
        public virtual string Name() => PascalToKebab(this.GetType().Name.Replace("Sample",""));
 | 
			
		||||
        public virtual (int Cols, int Rows) ConsoleSize => (82, 24);
 | 
			
		||||
        public virtual IEnumerable<(string Name, Action<Capabilities> CapabilitiesAction)> GetCapabilities()
 | 
			
		||||
        {
 | 
			
		||||
            return new (string Name, Action<Capabilities> CapabilitiesAction)[]
 | 
			
		||||
            {
 | 
			
		||||
                ("plain", capabilities =>
 | 
			
		||||
                {
 | 
			
		||||
                    capabilities.Unicode = false;
 | 
			
		||||
                    capabilities.Ansi = true;
 | 
			
		||||
                    capabilities.Interactive = true;
 | 
			
		||||
                    capabilities.Legacy = false;
 | 
			
		||||
                    capabilities.Links = false;
 | 
			
		||||
                    capabilities.ColorSystem = ColorSystem.Legacy;
 | 
			
		||||
                }),
 | 
			
		||||
                ("rich", capabilities =>
 | 
			
		||||
                {
 | 
			
		||||
                    capabilities.Unicode = true;
 | 
			
		||||
                    capabilities.Ansi = true;
 | 
			
		||||
                    capabilities.Interactive = true;
 | 
			
		||||
                    capabilities.Legacy = false;
 | 
			
		||||
                    capabilities.Links = false;
 | 
			
		||||
                    capabilities.ColorSystem = ColorSystem.TrueColor;
 | 
			
		||||
                }),
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string PascalToKebab(ReadOnlySpan<char> input)
 | 
			
		||||
        {
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            var previousUpper = true;
 | 
			
		||||
            foreach (var chr in input)
 | 
			
		||||
            {
 | 
			
		||||
                if (char.IsUpper(chr) && previousUpper == false)
 | 
			
		||||
                {
 | 
			
		||||
                    sb.Append('-');
 | 
			
		||||
                    previousUpper = true;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    previousUpper = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                sb.Append(char.ToLower(chr));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return sb.ToString();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal abstract class BaseCalendarSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (base.ConsoleSize.Cols, 12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class CalendarSample : BaseCalendarSample
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console) => console.Write(new Calendar(2020,10));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class CalendarCultureSample : BaseCalendarSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console) => console.Write(new Calendar(2020,10).Culture("sv-SE"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class CalendarHeader : BaseCalendarSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var calendar = new Calendar(2020,10);
 | 
			
		||||
            calendar.HeaderStyle(Style.Parse("blue bold"));
 | 
			
		||||
            console.Write(calendar);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class CalendarHighlightSample : BaseCalendarSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var calendar = new Calendar(2020, 10).HighlightStyle(Style.Parse("yellow bold"));
 | 
			
		||||
            calendar.AddCalendarEvent(2020, 10, 11);
 | 
			
		||||
            console.Write(calendar);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
using DocExampleGenerator;
 | 
			
		||||
using SixLabors.ImageSharp.Processing;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class CanvasImageSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var image = new CanvasImage("../../../examples/Console/Canvas/cake.png");
 | 
			
		||||
            image.MaxWidth(16);
 | 
			
		||||
            console.Write(image);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal class CanvasImageManipulationSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var image = new CanvasImage("../../../examples/Console/Canvas/cake.png");
 | 
			
		||||
            image.MaxWidth(24);
 | 
			
		||||
            image.BilinearResampler();
 | 
			
		||||
            image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
 | 
			
		||||
            console.Write(image);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								resources/scripts/Generator/Commands/Samples/CanvasSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								resources/scripts/Generator/Commands/Samples/CanvasSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class CanvasSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var canvas = new Canvas(16, 16);
 | 
			
		||||
 | 
			
		||||
            // Draw some shapes
 | 
			
		||||
            for(var i = 0; i < canvas.Width; i++)
 | 
			
		||||
            {
 | 
			
		||||
                // Cross
 | 
			
		||||
                canvas.SetPixel(i, i, Color.White);
 | 
			
		||||
                canvas.SetPixel(canvas.Width - i - 1, i, Color.White);
 | 
			
		||||
 | 
			
		||||
                // Border
 | 
			
		||||
                canvas.SetPixel(i, 0, Color.Red);
 | 
			
		||||
                canvas.SetPixel(0, i, Color.Green);
 | 
			
		||||
                canvas.SetPixel(i, canvas.Height - 1, Color.Blue);
 | 
			
		||||
                canvas.SetPixel(canvas.Width - 1, i, Color.Yellow);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Render the canvas
 | 
			
		||||
            console.Write(canvas);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								resources/scripts/Generator/Commands/Samples/Exceptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								resources/scripts/Generator/Commands/Samples/Exceptions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Security.Authentication;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    public class Exceptions
 | 
			
		||||
    {
 | 
			
		||||
        internal abstract class BaseExceptionSample : BaseSample
 | 
			
		||||
        {
 | 
			
		||||
            public override (int Cols, int Rows) ConsoleSize => (base.ConsoleSize.Cols, 12);
 | 
			
		||||
 | 
			
		||||
            protected readonly Exception Exception = null!;
 | 
			
		||||
 | 
			
		||||
            protected BaseExceptionSample()
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    DoMagic(42, null);
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    Exception = ex;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal class DefaultExceptionSample : BaseExceptionSample
 | 
			
		||||
        {
 | 
			
		||||
            public override void Run(IAnsiConsole console) => console.WriteException(Exception);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal class ShortenedExceptionSample : BaseExceptionSample
 | 
			
		||||
        {
 | 
			
		||||
            public override void Run(IAnsiConsole console) => console.WriteException(Exception, ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal class CustomColorsExceptionSample : BaseExceptionSample
 | 
			
		||||
        {
 | 
			
		||||
            public override void Run(IAnsiConsole console)
 | 
			
		||||
            {
 | 
			
		||||
                console.WriteException(Exception, new ExceptionSettings
 | 
			
		||||
                {
 | 
			
		||||
                    Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
 | 
			
		||||
                    Style = new ExceptionStyle
 | 
			
		||||
                    {
 | 
			
		||||
                        Exception = new Style().Foreground(Color.Grey),
 | 
			
		||||
                        Message = new Style().Foreground(Color.White),
 | 
			
		||||
                        NonEmphasized = new Style().Foreground(Color.Cornsilk1),
 | 
			
		||||
                        Parenthesis = new Style().Foreground(Color.Cornsilk1),
 | 
			
		||||
                        Method = new Style().Foreground(Color.Red),
 | 
			
		||||
                        ParameterName = new Style().Foreground(Color.Cornsilk1),
 | 
			
		||||
                        ParameterType = new Style().Foreground(Color.Red),
 | 
			
		||||
                        Path = new Style().Foreground(Color.Red),
 | 
			
		||||
                        LineNumber = new Style().Foreground(Color.Cornsilk1),
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void DoMagic(int foo, string[,] bar)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                CheckCredentials(foo, bar);
 | 
			
		||||
            }
 | 
			
		||||
            catch(Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                throw new InvalidOperationException("Whaaat?", ex);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void CheckCredentials(int qux, string[,] corgi)
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidCredentialException("The credentials are invalid.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								resources/scripts/Generator/Commands/Samples/FigletSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								resources/scripts/Generator/Commands/Samples/FigletSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    public class FigletSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (120, 24);
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.Write(new FigletText("Left aligned").LeftAligned().Color(Color.Red));
 | 
			
		||||
            console.Write(new FigletText("Centered").Centered().Color(Color.Green));
 | 
			
		||||
            console.Write(new FigletText("Right aligned").RightAligned().Color(Color.Blue));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								resources/scripts/Generator/Commands/Samples/InputSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								resources/scripts/Generator/Commands/Samples/InputSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
using DocExampleGenerator;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class InputSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var age = 0;
 | 
			
		||||
            var name = string.Empty;
 | 
			
		||||
            var sport = string.Empty;
 | 
			
		||||
            var password = string.Empty;
 | 
			
		||||
            var color = string.Empty;
 | 
			
		||||
 | 
			
		||||
            console.DisplayThenType(c => name = AskName(c), "Peter F↲");
 | 
			
		||||
            console.DisplayThenType(c => sport = AskSport(c), "football↲¦¦¦¦Hockey↲");
 | 
			
		||||
            console.DisplayThenType(c => age = AskAge(c), "Forty↲¦¦¦¦40↲");
 | 
			
		||||
            console.DisplayThenType(c => password = AskPassword(c), "hunter2↲");
 | 
			
		||||
            console.DisplayThenType(c => color = AskColor(c), "↲");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            AnsiConsole.Render(new Rule("[yellow]Results[/]").RuleStyle("grey").LeftAligned());
 | 
			
		||||
            AnsiConsole.Render(new Table().AddColumns("[grey]Question[/]", "[grey]Answer[/]")
 | 
			
		||||
                .RoundedBorder()
 | 
			
		||||
                .BorderColor(Color.Grey)
 | 
			
		||||
                .AddRow("[grey]Name[/]", name)
 | 
			
		||||
                .AddRow("[grey]Favorite sport[/]", sport)
 | 
			
		||||
                .AddRow("[grey]Age[/]", age.ToString())
 | 
			
		||||
                .AddRow("[grey]Password[/]", password)
 | 
			
		||||
                .AddRow("[grey]Favorite color[/]", string.IsNullOrEmpty(color) ? "Unknown" : color));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string AskName(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[yellow]Strings[/]").RuleStyle("grey").LeftAligned());
 | 
			
		||||
            var name = console.Ask<string>("What's your [green]name[/]?");
 | 
			
		||||
            return name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private static string AskSport(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[yellow]Choices[/]").RuleStyle("grey").LeftAligned());
 | 
			
		||||
 | 
			
		||||
            return console.Prompt(
 | 
			
		||||
                new TextPrompt<string>("What's your [green]favorite sport[/]?")
 | 
			
		||||
                    .InvalidChoiceMessage("[red]That's not a sport![/]")
 | 
			
		||||
                    .DefaultValue("Sport?")
 | 
			
		||||
                    .AddChoice("Soccer")
 | 
			
		||||
                    .AddChoice("Hockey")
 | 
			
		||||
                    .AddChoice("Basketball"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static int AskAge(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[yellow]Integers[/]").RuleStyle("grey").LeftAligned());
 | 
			
		||||
 | 
			
		||||
            return console.Prompt(
 | 
			
		||||
                new TextPrompt<int>("How [green]old[/] are you?")
 | 
			
		||||
                    .PromptStyle("green")
 | 
			
		||||
                    .ValidationErrorMessage("[red]That's not a valid age[/]")
 | 
			
		||||
                    .Validate(age =>
 | 
			
		||||
                    {
 | 
			
		||||
                        return age switch
 | 
			
		||||
                        {
 | 
			
		||||
                            <= 0 => ValidationResult.Error("[red]You must at least be 1 years old[/]"),
 | 
			
		||||
                            >= 123 => ValidationResult.Error("[red]You must be younger than the oldest person alive[/]"),
 | 
			
		||||
                            _ => ValidationResult.Success(),
 | 
			
		||||
                        };
 | 
			
		||||
                    }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string AskPassword(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[yellow]Secrets[/]").RuleStyle("grey").LeftAligned());
 | 
			
		||||
 | 
			
		||||
            return console.Prompt(
 | 
			
		||||
                new TextPrompt<string>("Enter [green]password[/]?")
 | 
			
		||||
                    .PromptStyle("red")
 | 
			
		||||
                    .Secret());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string AskColor(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[yellow]Optional[/]").RuleStyle("grey").LeftAligned());
 | 
			
		||||
 | 
			
		||||
            return console.Prompt(
 | 
			
		||||
                new TextPrompt<string>("[grey][[Optional]][/] What is your [green]favorite color[/]?")
 | 
			
		||||
                    .AllowEmpty());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								resources/scripts/Generator/Commands/Samples/LiveSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								resources/scripts/Generator/Commands/Samples/LiveSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class LiveSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (120, 20);
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var table = new Table();
 | 
			
		||||
 | 
			
		||||
            // Animate
 | 
			
		||||
            console.Live(table)
 | 
			
		||||
                .AutoClear(false)
 | 
			
		||||
                .Overflow(VerticalOverflow.Ellipsis)
 | 
			
		||||
                .Cropping(VerticalOverflowCropping.Top)
 | 
			
		||||
                .Start(ctx =>
 | 
			
		||||
                {
 | 
			
		||||
                    void Update(int delay, Action action)
 | 
			
		||||
                    {
 | 
			
		||||
                        action();
 | 
			
		||||
                        ctx.Refresh();
 | 
			
		||||
                        Thread.Sleep(delay);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Columns
 | 
			
		||||
                    Update(230, () => table.AddColumn("Release date"));
 | 
			
		||||
                    Update(230, () => table.AddColumn("Title"));
 | 
			
		||||
                    Update(230, () => table.AddColumn("Budget"));
 | 
			
		||||
                    Update(230, () => table.AddColumn("Opening Weekend"));
 | 
			
		||||
                    Update(230, () => table.AddColumn("Box office"));
 | 
			
		||||
 | 
			
		||||
                    // Rows
 | 
			
		||||
                    Update(70, () => table.AddRow("May 25, 1977", "[yellow]Star Wars[/] [grey]Ep.[/] [u]IV[/]", "$11,000,000", "$1,554,475", "$775,398,007"));
 | 
			
		||||
                    Update(70, () => table.AddRow("May 21, 1980", "[yellow]Star Wars[/] [grey]Ep.[/] [u]V[/]", "$18,000,000", "$4,910,483", "$547,969,004"));
 | 
			
		||||
                    Update(70, () => table.AddRow("May 25, 1983", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VI[/]", "$32,500,000", "$23,019,618", "$475,106,177"));
 | 
			
		||||
                    Update(70, () => table.AddRow("May 19, 1999", "[yellow]Star Wars[/] [grey]Ep.[/] [u]I[/]", "$115,000,000", "$64,810,870", "$1,027,044,677"));
 | 
			
		||||
                    Update(70, () => table.AddRow("May 16, 2002", "[yellow]Star Wars[/] [grey]Ep.[/] [u]II[/]", "$115,000,000", "$80,027,814", "$649,436,358"));
 | 
			
		||||
                    Update(70, () => table.AddRow("May 19, 2005", "[yellow]Star Wars[/] [grey]Ep.[/] [u]III[/]", "$113,000,000", "$108,435,841", "$850,035,635"));
 | 
			
		||||
                    Update(70, () => table.AddRow("Dec 18, 2015", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VII[/]", "$245,000,000", "$247,966,675", "$2,068,223,624"));
 | 
			
		||||
                    Update(70, () => table.AddRow("Dec 15, 2017", "[yellow]Star Wars[/] [grey]Ep.[/] [u]VIII[/]", "$317,000,000", "$220,009,584", "$1,333,539,889"));
 | 
			
		||||
                    Update(70, () => table.AddRow("Dec 20, 2019", "[yellow]Star Wars[/] [grey]Ep.[/] [u]IX[/]", "$245,000,000", "$177,383,864", "$1,074,114,248"));
 | 
			
		||||
 | 
			
		||||
                    // Column footer
 | 
			
		||||
                    Update(230, () => table.Columns[2].Footer("$1,633,000,000"));
 | 
			
		||||
                    Update(230, () => table.Columns[3].Footer("$928,119,224"));
 | 
			
		||||
                    Update(400, () => table.Columns[4].Footer("$10,318,030,576"));
 | 
			
		||||
 | 
			
		||||
                    // Column alignment
 | 
			
		||||
                    Update(230, () => table.Columns[2].RightAligned());
 | 
			
		||||
                    Update(230, () => table.Columns[3].RightAligned());
 | 
			
		||||
                    Update(400, () => table.Columns[4].RightAligned());
 | 
			
		||||
 | 
			
		||||
                    // Column titles
 | 
			
		||||
                    Update(70, () => table.Columns[0].Header("[bold]Release date[/]"));
 | 
			
		||||
                    Update(70, () => table.Columns[1].Header("[bold]Title[/]"));
 | 
			
		||||
                    Update(70, () => table.Columns[2].Header("[red bold]Budget[/]"));
 | 
			
		||||
                    Update(70, () => table.Columns[3].Header("[green bold]Opening Weekend[/]"));
 | 
			
		||||
                    Update(400, () => table.Columns[4].Header("[blue bold]Box office[/]"));
 | 
			
		||||
 | 
			
		||||
                    // Footers
 | 
			
		||||
                    Update(70, () => table.Columns[2].Footer("[red bold]$1,633,000,000[/]"));
 | 
			
		||||
                    Update(70, () => table.Columns[3].Footer("[green bold]$928,119,224[/]"));
 | 
			
		||||
                    Update(400, () => table.Columns[4].Footer("[blue bold]$10,318,030,576[/]"));
 | 
			
		||||
 | 
			
		||||
                    // Title
 | 
			
		||||
                    Update(500, () => table.Title("Star Wars Movies"));
 | 
			
		||||
                    Update(400, () => table.Title("[[ [yellow]Star Wars Movies[/] ]]"));
 | 
			
		||||
 | 
			
		||||
                    // Borders
 | 
			
		||||
                    Update(230, () => table.BorderColor(Color.Yellow));
 | 
			
		||||
                    Update(230, () => table.MinimalBorder());
 | 
			
		||||
                    Update(230, () => table.SimpleBorder());
 | 
			
		||||
                    Update(230, () => table.SimpleHeavyBorder());
 | 
			
		||||
 | 
			
		||||
                    // Caption
 | 
			
		||||
                    Update(400, () => table.Caption("[[ [blue]THE END[/] ]]"));
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
using DocExampleGenerator;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class MultiSelectionSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (base.ConsoleSize.Cols, 14);
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.DisplayThenType(AskFruit, "↓↓ ¦¦↑↑ ¦¦ ¦¦↓ ↓↓↓↓↓ ↓↓↓↓ ¦¦↲");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void AskFruit(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var favorites = AnsiConsole.Prompt(
 | 
			
		||||
                new MultiSelectionPrompt<string>()
 | 
			
		||||
                    .PageSize(10)
 | 
			
		||||
                    .Title("What are your [green]favorite fruits[/]?")
 | 
			
		||||
                    .MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
 | 
			
		||||
                    .InstructionsText("[grey](Press [blue]<space>[/] to toggle a fruit, [green]<enter>[/] to accept)[/]")
 | 
			
		||||
                    .AddChoiceGroup("Berries", new[]
 | 
			
		||||
                    {
 | 
			
		||||
                        "Blackcurrant", "Blueberry", "Cloudberry",
 | 
			
		||||
                        "Elderberry", "Honeyberry", "Mulberry"
 | 
			
		||||
                    })
 | 
			
		||||
                    .AddChoices(new[]
 | 
			
		||||
                    {
 | 
			
		||||
                        "Apple", "Apricot", "Avocado", "Banana",
 | 
			
		||||
                        "Cherry", "Cocunut", "Date", "Dragonfruit", "Durian",
 | 
			
		||||
                        "Egg plant",  "Fig", "Grape", "Guava",
 | 
			
		||||
                        "Jackfruit", "Jambul", "Kiwano", "Kiwifruit", "Lime", "Lylo",
 | 
			
		||||
                        "Lychee", "Melon", "Nectarine", "Orange", "Olive"
 | 
			
		||||
                    }));
 | 
			
		||||
 | 
			
		||||
            console.MarkupLine("Your selected: [yellow]{0}[/]", string.Join(',', favorites));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,87 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class ProgressSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (base.ConsoleSize.Cols, 10);
 | 
			
		||||
 | 
			
		||||
        public override IEnumerable<(string Name, Action<Capabilities> CapabilitiesAction)> GetCapabilities()
 | 
			
		||||
        {
 | 
			
		||||
            yield return ("non-interactive", capabilities =>
 | 
			
		||||
            {
 | 
			
		||||
                capabilities.Ansi = false;
 | 
			
		||||
                capabilities.Interactive = false;
 | 
			
		||||
                capabilities.Legacy = false;
 | 
			
		||||
                capabilities.Unicode = true;
 | 
			
		||||
                capabilities.ColorSystem = ColorSystem.TrueColor;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            foreach (var capability in base.GetCapabilities())
 | 
			
		||||
            {
 | 
			
		||||
                yield return capability;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            // Show progress
 | 
			
		||||
            console.Progress()
 | 
			
		||||
                .AutoClear(false)
 | 
			
		||||
                .Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn(), new RemainingTimeColumn(), new SpinnerColumn())
 | 
			
		||||
                .Start(ctx =>
 | 
			
		||||
                {
 | 
			
		||||
                    var random = new Random(122978);
 | 
			
		||||
 | 
			
		||||
                    // Create some tasks
 | 
			
		||||
                    var tasks = CreateTasks(ctx, random);
 | 
			
		||||
                    var warpTask = ctx.AddTask("Going to warp", autoStart: false).IsIndeterminate();
 | 
			
		||||
 | 
			
		||||
                    // Wait for all tasks (except the indeterminate one) to complete
 | 
			
		||||
                    while (!ctx.IsFinished)
 | 
			
		||||
                    {
 | 
			
		||||
                        // Increment progress
 | 
			
		||||
                        foreach (var (task, increment) in tasks)
 | 
			
		||||
                        {
 | 
			
		||||
                            task.Increment(random.NextDouble() * increment);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Simulate some delay
 | 
			
		||||
                        Thread.Sleep(100);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Now start the "warp" task
 | 
			
		||||
                    warpTask.StartTask();
 | 
			
		||||
                    warpTask.IsIndeterminate(false);
 | 
			
		||||
                    while (!ctx.IsFinished)
 | 
			
		||||
                    {
 | 
			
		||||
                        warpTask.Increment(12 * random.NextDouble());
 | 
			
		||||
 | 
			
		||||
                        // Simulate some delay
 | 
			
		||||
                        Thread.Sleep(100);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static List<(ProgressTask Task, int Delay)> CreateTasks(ProgressContext progress, Random random)
 | 
			
		||||
        {
 | 
			
		||||
            var tasks = new List<(ProgressTask, int)>();
 | 
			
		||||
 | 
			
		||||
            var names = new[]
 | 
			
		||||
            {
 | 
			
		||||
                "Retriculating algorithms", "Colliding splines", "Solving quarks", "Folding data structures",
 | 
			
		||||
                "Rerouting capacitators "
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            for (var i = 0; i < 5; i++)
 | 
			
		||||
            {
 | 
			
		||||
                tasks.Add((progress.AddTask(names[i]), random.Next(2, 10)));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return tasks;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								resources/scripts/Generator/Commands/Samples/RuleSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								resources/scripts/Generator/Commands/Samples/RuleSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class RuleSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (82, 10);
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.Write(new Rule());
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[blue]Left aligned[/]").LeftAligned().RuleStyle("red"));
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[green]Centered[/]").Centered().RuleStyle("green"));
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
            console.Write(new Rule("[red]Right aligned[/]").RightAligned().RuleStyle("blue"));
 | 
			
		||||
            console.WriteLine();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,29 @@
 | 
			
		||||
using DocExampleGenerator;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class SelectionSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (base.ConsoleSize.Cols, 14);
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.DisplayThenType(AskFruit, "↓↓↓¦¦¦¦ ");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void AskFruit(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            // Ask for the user's favorite fruit
 | 
			
		||||
            var fruit = console.Prompt(
 | 
			
		||||
                new SelectionPrompt<string>()
 | 
			
		||||
                    .Title("What's your [green]favorite fruit[/]?")
 | 
			
		||||
                    .PageSize(10)
 | 
			
		||||
                    .MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
 | 
			
		||||
                    .AddChoices(new [] {"Apple", "Apricot", "Avocado", "Banana", "Blackcurrant", "Blueberry", "Cherry", "Cloudberry", "Cocunut"}));
 | 
			
		||||
 | 
			
		||||
            // Echo the fruit back to the terminal
 | 
			
		||||
            console.WriteLine($"I agree. {fruit} is tasty!");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								resources/scripts/Generator/Commands/Samples/StatusSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								resources/scripts/Generator/Commands/Samples/StatusSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class StatusSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (base.ConsoleSize.Cols, 10);
 | 
			
		||||
 | 
			
		||||
        private static void WriteLogMessage(string message)
 | 
			
		||||
        {
 | 
			
		||||
            AnsiConsole.MarkupLine($"[grey]LOG:[/] {message}[grey]...[/]");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            console.Status()
 | 
			
		||||
                .AutoRefresh(true)
 | 
			
		||||
                .Spinner(Spinner.Known.Default)
 | 
			
		||||
                .Start("[yellow]Initializing warp drive[/]", ctx =>
 | 
			
		||||
                {
 | 
			
		||||
                    // Initialize
 | 
			
		||||
                    Thread.Sleep(3000);
 | 
			
		||||
                    WriteLogMessage("Starting gravimetric field displacement manifold");
 | 
			
		||||
                    Thread.Sleep(1000);
 | 
			
		||||
                    WriteLogMessage("Warming up deuterium chamber");
 | 
			
		||||
                    Thread.Sleep(2000);
 | 
			
		||||
                    WriteLogMessage("Generating antideuterium");
 | 
			
		||||
 | 
			
		||||
                    // Warp nacelles
 | 
			
		||||
                    Thread.Sleep(3000);
 | 
			
		||||
                    ctx.Spinner(Spinner.Known.BouncingBar);
 | 
			
		||||
                    ctx.Status("[bold blue]Unfolding warp nacelles[/]");
 | 
			
		||||
                    WriteLogMessage("Unfolding left warp nacelle");
 | 
			
		||||
                    Thread.Sleep(2000);
 | 
			
		||||
                    WriteLogMessage("Left warp nacelle [green]online[/]");
 | 
			
		||||
                    WriteLogMessage("Unfolding right warp nacelle");
 | 
			
		||||
                    Thread.Sleep(1000);
 | 
			
		||||
                    WriteLogMessage("Right warp nacelle [green]online[/]");
 | 
			
		||||
 | 
			
		||||
                    // Warp bubble
 | 
			
		||||
                    Thread.Sleep(3000);
 | 
			
		||||
                    ctx.Spinner(Spinner.Known.Star2);
 | 
			
		||||
                    ctx.Status("[bold blue]Generating warp bubble[/]");
 | 
			
		||||
                    Thread.Sleep(3000);
 | 
			
		||||
                    ctx.Spinner(Spinner.Known.Star);
 | 
			
		||||
                    ctx.Status("[bold blue]Stabilizing warp bubble[/]");
 | 
			
		||||
 | 
			
		||||
                    // Safety
 | 
			
		||||
                    ctx.Spinner(Spinner.Known.Monkey);
 | 
			
		||||
                    ctx.Status("[bold blue]Performing safety checks[/]");
 | 
			
		||||
                    WriteLogMessage("Enabling interior dampening");
 | 
			
		||||
                    Thread.Sleep(2000);
 | 
			
		||||
                    WriteLogMessage("Interior dampening [green]enabled[/]");
 | 
			
		||||
 | 
			
		||||
                    // Warp!
 | 
			
		||||
                    Thread.Sleep(3000);
 | 
			
		||||
                    ctx.Spinner(Spinner.Known.Moon);
 | 
			
		||||
                    WriteLogMessage("Preparing for warp");
 | 
			
		||||
                    Thread.Sleep(1000);
 | 
			
		||||
                    for (var warp = 1; warp < 10; warp++)
 | 
			
		||||
                    {
 | 
			
		||||
                        ctx.Status($"[bold blue]Warp {warp}[/]");
 | 
			
		||||
                        Thread.Sleep(500);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            // Done
 | 
			
		||||
            AnsiConsole.MarkupLine("[bold green]Crusing at Warp 9.8[/]");        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								resources/scripts/Generator/Commands/Samples/TableSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								resources/scripts/Generator/Commands/Samples/TableSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class TableSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override (int Cols, int Rows) ConsoleSize => (100, 30);
 | 
			
		||||
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var simple = new Table()
 | 
			
		||||
                .Border(TableBorder.Square)
 | 
			
		||||
                .BorderColor(Color.Red)
 | 
			
		||||
                .AddColumn(new TableColumn("[u]CDE[/]").Footer("EDC").Centered())
 | 
			
		||||
                .AddColumn(new TableColumn("[u]FED[/]").Footer("DEF"))
 | 
			
		||||
                .AddColumn(new TableColumn("[u]IHG[/]").Footer("GHI"))
 | 
			
		||||
                .AddRow("Hello", "[red]World![/]", "")
 | 
			
		||||
                .AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]")
 | 
			
		||||
                .AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
 | 
			
		||||
 | 
			
		||||
            var second = new Table()
 | 
			
		||||
                .Border(TableBorder.Rounded)
 | 
			
		||||
                .BorderColor(Color.Green)
 | 
			
		||||
                .AddColumn(new TableColumn("[u]Foo[/]"))
 | 
			
		||||
                .AddColumn(new TableColumn("[u]Bar[/]"))
 | 
			
		||||
                .AddColumn(new TableColumn("[u]Baz[/]"))
 | 
			
		||||
                .AddRow("Hello", "[red]World![/]", "")
 | 
			
		||||
                .AddRow(simple, new Text("Whaaat"), new Text("Lolz"))
 | 
			
		||||
                .AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
 | 
			
		||||
 | 
			
		||||
            var table = new Table()
 | 
			
		||||
                .Centered()
 | 
			
		||||
                .Border(TableBorder.DoubleEdge)
 | 
			
		||||
                .Title("TABLE [yellow]TITLE[/]")
 | 
			
		||||
                .Caption("TABLE [yellow]CAPTION[/]")
 | 
			
		||||
                .AddColumn(new TableColumn(new Panel("[u]ABC[/]").BorderColor(Color.Red)).Footer("[u]FOOTER 1[/]"))
 | 
			
		||||
                .AddColumn(new TableColumn(new Panel("[u]DEF[/]").BorderColor(Color.Green)).Footer("[u]FOOTER 2[/]"))
 | 
			
		||||
                .AddColumn(new TableColumn(new Panel("[u]GHI[/]").BorderColor(Color.Blue)).Footer("[u]FOOTER 3[/]"))
 | 
			
		||||
                .AddRow(new Text("Hello").Centered(), new Markup("[red]World![/]"), Text.Empty)
 | 
			
		||||
                .AddRow(second, new Text("Whaaat"), new Text("Lol"))
 | 
			
		||||
                .AddRow(new Markup("[blue]Hej[/]").Centered(), new Markup("[yellow]Världen![/]"), Text.Empty);
 | 
			
		||||
 | 
			
		||||
            console.Write(table);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								resources/scripts/Generator/Commands/Samples/TreeSample.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								resources/scripts/Generator/Commands/Samples/TreeSample.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands.Samples
 | 
			
		||||
{
 | 
			
		||||
    internal class TreeSample : BaseSample
 | 
			
		||||
    {
 | 
			
		||||
        public override void Run(IAnsiConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            // Create the tree
 | 
			
		||||
            var tree = new Tree("Root")
 | 
			
		||||
                .Style(Style.Parse("red"))
 | 
			
		||||
                .Guide(TreeGuide.Line);
 | 
			
		||||
 | 
			
		||||
            // Add some nodes
 | 
			
		||||
            var foo = tree.AddNode("[yellow]Nest objects like tables[/]");
 | 
			
		||||
            var table = foo.AddNode(new Table()
 | 
			
		||||
                .RoundedBorder()
 | 
			
		||||
                .AddColumn("First")
 | 
			
		||||
                .AddColumn("Second")
 | 
			
		||||
                .AddRow("1", "2")
 | 
			
		||||
                .AddRow("3", "4")
 | 
			
		||||
                .AddRow("5", "6"));
 | 
			
		||||
 | 
			
		||||
            table.AddNode("[blue]with[/]");
 | 
			
		||||
            table.AddNode("[blue]multiple[/]");
 | 
			
		||||
            table.AddNode("[blue]children too[/]");
 | 
			
		||||
 | 
			
		||||
            var bar = tree.AddNode("Any IRenderable can be nested, such as [yellow]calendars[/]");
 | 
			
		||||
            bar.AddNode(new Calendar(2020, 12)
 | 
			
		||||
                .Border(TableBorder.Rounded)
 | 
			
		||||
                .BorderStyle(new Style(Color.Green3_1))
 | 
			
		||||
                .AddCalendarEvent(2020, 12, 12)
 | 
			
		||||
                .HideHeader());
 | 
			
		||||
 | 
			
		||||
            console.Write(tree);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using Generator.Models;
 | 
			
		||||
using Scriban;
 | 
			
		||||
using Spectre.Cli;
 | 
			
		||||
using Spectre.Console.Cli;
 | 
			
		||||
using Spectre.IO;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <OutputType>Exe</OutputType>
 | 
			
		||||
    <TargetFramework>netcoreapp3.1</TargetFramework>
 | 
			
		||||
    <LangVersion>default</LangVersion>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
@@ -44,10 +45,11 @@
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="AngleSharp" Version="0.14.0" />
 | 
			
		||||
    <PackageReference Include="Humanizer.Core" Version="2.8.26" />
 | 
			
		||||
    <PackageReference Include="InputSimulatorCore" Version="1.0.5" />
 | 
			
		||||
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
 | 
			
		||||
    <PackageReference Include="Scriban" Version="2.1.3" />
 | 
			
		||||
    <PackageReference Include="Spectre.Cli" Version="0.36.1-preview.0.6" />
 | 
			
		||||
    <PackageReference Include="Spectre.Console" Version="0.39.1-preview.0.27" />
 | 
			
		||||
    <PackageReference Include="Spectre.Console.ImageSharp" Version="0.39.1-preview.0.27" />
 | 
			
		||||
    <PackageReference Include="Spectre.IO" Version="0.1.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
using Generator.Commands;
 | 
			
		||||
using Spectre.Cli;
 | 
			
		||||
using Spectre.Console.Cli;
 | 
			
		||||
 | 
			
		||||
namespace Generator
 | 
			
		||||
{
 | 
			
		||||
@@ -13,6 +13,7 @@ namespace Generator
 | 
			
		||||
                config.AddCommand<ColorGeneratorCommand>("colors");
 | 
			
		||||
                config.AddCommand<EmojiGeneratorCommand>("emoji");
 | 
			
		||||
                config.AddCommand<SpinnerGeneratorCommand>("spinners");
 | 
			
		||||
                config.AddCommand<SampleCommand>("samples");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return app.Run(args);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user