Compare commits

...

246 Commits

Author SHA1 Message Date
Phil Scott
f5a9c0ca26 Removes automatic registration of settings
Original intention was to register Settings automatically for DI. This ran into problem when the container verifies the configuration is valid for a settings using the constructor for initialization. It tries to resolve the parameters and fails.

This removes the automatic registration and falls back ActivatorCreateInstance when no Setting is registered.
2021-04-18 22:41:05 +02:00
Loïc Sharma
23564612c1 Make AsyncCommand a little more discoverable (#375) 2021-04-18 09:35:37 +02:00
Phil Scott
f2b8afffb3 Marks Spectre.Console.Testing as not a test project
Probably something that only bothers me, but I'm in a habit of running dotnet test at the solution level. It was discovering this project as a test project even though it isn't. This produces an error complaining about not having a testhost.dll. I'm pretty sure this comes in via a props when xunit is referenced. 

This attribute in the csproj marks the project explicitly as not a test project
2021-04-17 09:30:33 +02:00
Patrik Svensson
3e2eea730b Add output abstraction and reorganize profile
* Moves ColorSystem from Profile to Capabilities
* Renames Tty to IsTerminal
* Adds IAnsiConsoleOutput to make output more flexible

Closes #343
Closes #359
Closes #369
2021-04-13 21:39:54 -04:00
Phil Scott
bc9f610258 Added "--hidden" param to explain feature
Probably shouldn't include the hidden commands by default. This lets the user show them if needed.
2021-04-13 17:40:55 +02:00
Phil Scott
ae96606ab7 Adds default command to explain feature 2021-04-13 17:40:55 +02:00
Phil Scott
41ccc0b464 Adds CLI explain command
Wanted a command to break down how Spectre views the command model. This outputs all the relevant settings in a tree. You can get a short explanation for all the commands, or a detailed explanation for all commands (there is a flag to go vice versa on the detailed view if you want)

app cli explain
app cli explain myappcommand
app cli explain -d
2021-04-12 17:40:31 +02:00
Patrik Svensson
3545e0f6b5 Add example infrastructure
* Add "Shared" projects for all examples
* Update "Colors" example with better TrueColor demo
* Use same namespace for all examples
2021-04-11 22:03:13 -04:00
Patrik Svensson
2fe2bb3c32 Add parameterless Clear method for IAnsiConsole
Closes #338
2021-04-11 22:01:14 -04:00
Patrik Svensson
1fc6f22ea9 Remove Style.Clone method
Closes #362
2021-04-11 21:58:58 -04:00
Patrik Svensson
6a5c507936 Rename 'Demo' example to 'Showcase' 2021-04-09 22:01:05 +02:00
Patrik Svensson
efa3d3b130 Add NuGet.Config 2021-04-09 08:45:30 -04:00
Patrik Svensson
6007fcaafc Update to .NET SDK 5.0.202 2021-04-09 07:48:10 -04:00
Patrik Svensson
13ac38ed04 Fix color system mapping bug
Closes #342
2021-04-08 12:18:54 -04:00
Patrik Svensson
ca036f6543 Add demo example 2021-04-07 20:32:07 -04:00
Phil Scott
36ec3d1fd3 Adds rune width caching for cell length calculations 2021-04-07 23:59:23 +02:00
Patrik Svensson
fe5096dceb Fixes color system detection bug
If an application runs on Windows 10.0.15063 or above, on a
runtime prior to net5.0, the color system detection will fail
and fall back to 8-bit color support.

The reason for this is because the behavior of
Environment.OSVersion.Version differs between runtimes. Unless you're
running on net5.0, both the major and build version components will
not reflect those in the actual Windows version.
2021-04-07 11:15:45 -04:00
Christian Wischenbart
39b59c8d4a Cleanup AnsiSequences.cs
1. Update CSI constant to include the [ character.
See ECMA-48 Section 8.3.16
https://www.ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf

2. Use string interpolation, because it's easier to read
(and internally uses a StringBuilder)

3. Add ESC constant, because the AnsiBuilder needs it to create links.

4. Remove unused SGR overload.
2021-04-06 22:51:42 +02:00
Phil Scott
8cf7794852 Adding unit tests for settings constructor 2021-04-06 22:48:51 +02:00
Phil Scott
4edc647fdd Falls back to null for settings constructor 2021-04-06 22:48:51 +02:00
Christian Wischenbart
be45a0ff4e Fix AnsiConsoleBackend.Clear
1. Add an ED3 command to clear the scroll buffer.

This command is not in the original ANSI terminal control sequences but
was added later to XTerm to account for the fact that most modern
terminals have a scroll-buffer.

https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-J.1C8A

This command is now awailable in basically
all terminals with scroll-buffers

2. Change CUP coordinates to 1, 1

The coordinates 0, 0 also worked, but strictly speaking they are outside
the available screen area and are capped to 1, 1 anyways.

This commit fixes #337
2021-04-06 22:42:03 +02:00
Christian Wischenbart
256fcdd27f Remove redundant Style constructor. 2021-04-06 07:30:31 -04:00
Patrik Svensson
dafbfe63ba Update link to docs site 2021-04-05 17:54:32 +02:00
Patrik Svensson
a2ab522516 Add CNAME 2021-04-05 17:45:29 +02:00
Patrik Svensson
8778ab1739 Set new host for docs 2021-04-05 17:41:18 +02:00
Patrik Svensson
693e1fa170 Update links, references and copyright 2021-04-05 16:59:09 +02:00
Patrik Svensson
4b37a4708f Update documentation 2021-04-05 16:48:02 +02:00
Phil Scott
a690ce4955 Marks nullable bools as flags too 2021-04-05 16:14:13 +02:00
Andreia Gaita
759b16aed9 Fix OS version detection 2021-04-04 09:28:20 -04:00
Phil Scott
254880e93a Replaces emoji regex with ReadOnlySpan implementation
The RegEx runtime perf was never anything noticeable - it was the startup time that was eating over a third of time during initialization.

This shaves 200ms off the startup time.
2021-04-04 04:10:25 +02:00
Patrik Svensson
6f16081f42 Add support for indeterminate progress
This commit also changes the behavior of ProgressContext.IsFinished.
Only tasks that have been started will be taken into consideration,
and not indeterminate tasks.

Closes #329
Closes #331
2021-04-03 09:42:49 -04:00
MB
6121203fee Rename tree to root so the example compiles.
The 'root' variable does not exist in current context. Either should call Render(tree) or have it renamed to root. I've chosen root as it's more consistent with the examples later on.
2021-04-02 23:32:15 +02:00
Phil Scott
9204671b27 Uses Environment.TickCount for seed instead of DateTime.Now 2021-04-02 18:52:18 +02:00
Phil Scott
c765bbd0dd Uses OSVersion instead of RegEx to detect Windows Build info
Perf improvement.
2021-04-02 18:51:30 +02:00
Thomas Freudenberg
6bceac8a5e enable disposing ITypeResolver 2021-03-30 00:53:38 +02:00
Patrik Svensson
1ed7e65fcb Make VT-100 sequences easier to understand 2021-03-28 12:51:19 -04:00
Patrik Svensson
20650f1e7e Change IAnsiConsole to render IRenderable
This makes it possible for encoders to output better representation
of the actual objects instead of working with chopped up segments.

* IAnsiConsole.Write now takes an IRenderable instead of segments
* Calculating cell width does no longer require a render context
* Removed RenderContext.LegacyConsole
* Removed RenderContext.Encoding
* Added Capabilities.Unicode
2021-03-28 09:06:06 -04:00
Alexey Golub
2ba6da3514 Respect encoding of TextWriter provided to AnsiConsole.Create(...) 2021-03-25 21:19:49 +01:00
Alexey Golub
8830779875 Add params to ProgressExtensions.Columns(...)
This way you can omit `new ProgressColumn[] { ... }` and just list the columns separated by comma.
2021-03-25 21:11:51 +01:00
Patrik Svensson
9c46c21e27 Fix argument order
Closes #319
2021-03-24 18:58:17 -04:00
Reilly Wood
c643ec735d Fix documentation for ProgressContext.AddTask 2021-03-24 07:34:56 -04:00
Phil Scott
b17eabaa1f Adds helper overloads for Markup calls without args
Without specific overloads without the args string.format will get called even if it's not needed. 

This closes #309
2021-03-22 19:14:59 +01:00
Patrik Svensson
7f6f2437b1 Add support for exclusive mode 2021-03-15 13:14:40 -04:00
Patrik Svensson
c2bab0ebf8 Allow custom instructions for prompts
Closes #229
2021-03-14 21:27:44 -04:00
Patrik Svensson
9502aaf2b9 Allow markup in selection prompts
Closes #221
2021-03-14 21:27:44 -04:00
Patrik Svensson
57a8e6ccc1 Support Home, End, PgUp, and PgDown in prompts
Closes #296
2021-03-14 21:27:44 -04:00
Patrik Svensson
8c099a0038 Add Elmah.io as sponsor 2021-03-14 21:17:56 -04:00
Bastian Eicher
08b65cfa47 Fix Windows ANSI support detection with redirected stderr 2021-03-14 23:41:07 +01:00
Christopher-Marcel Esser
2540f48622 Hide examples of hidden commands 2021-03-13 23:21:48 +01:00
Phil Scott
e4dda283bb Adds overloads for MarkUp methods without args
These methods don't require a string.format call so we'll directly call the Render method without a call to string.format.

Added bonus of a a couple fewer allocations too.
2021-03-08 15:04:55 +01:00
Phil Scott
da9c6ee4c2 Add IProgress<double> to ProgressTask.cs
Makes the Report method an explicit implementation to allow for better interoperability with standard .NET progress functionality while keeping backwards compatibility with existing ProgressTask functionality.

Closes #285
2021-03-07 09:24:44 +01:00
Phil Scott
855127f32a Changes progress task IsFinished to account for stopped tasks
Previous behavior was that the only way to get a task to a finished state was to artificially set the Value to MaxValue.

With this change StopTask() will also complete the task with the change that a task cannot be restarted.
2021-03-07 09:24:21 +01:00
stf
fa731070d8 update the docs
To improve discoveratbility of the new option
2021-03-04 07:47:00 -05:00
stf
ef08c5bf2b Improve the unit test around HideCompleted 2021-03-04 07:47:00 -05:00
stf
1c769c6610 Add Progress.HideCompleted 2021-03-04 07:47:00 -05:00
Phil Scott
1cd335e785 Serilog example for logging 2021-03-04 08:39:53 +01:00
Patrik Svensson
29e6e34f83 Support setting the static console 2021-03-01 15:22:35 -05:00
Phil Scott
bff3438a5a using loop instead of linq
In both of these loops context is captured preventing caching of the lambda. this results in a pretty significant amount of allocations especially with progress bars that constantly are remeasuring
2021-03-01 08:22:45 +01:00
Oskar Klintrot
c64884854f Make it possible to set Value directly 2021-02-25 11:56:32 +01:00
Phil Scott
3a42c0a119 Adds DotSettings and tweaks editoconfigs for tests
R# and Rider have quite a bit of noise related to documentation in the testing projects so this disables those warnings.

In the main projects, R# and Rider complain loudly about the namespaces not matching the file structure. The DotSettings file disables that warning.

Once you get rid of that noise there are quite a few opportunities for trimming out redundant code that R# points out especially with the nullable support enabled, plus there are some bugs related to multiple enumerations worth looking into I think.
2021-02-23 22:34:33 +01:00
Thomas Freudenberg
525b414ff8 Make alignment of TaskDescriptionColumn configurable 2021-02-16 23:33:47 +01:00
Thomas Freudenberg
ed0fb29be4 Make default answer for confirmation prompt configurable 2021-02-16 23:32:49 +01:00
Phil Scott
04d0e663d5 Extends maximum size of remaining and elapsed time displayed, plus a failsafe
Elapsed and remaining now support > 9 hours, and if a timespan can't be rendered in that size **:**:** will be displayed
2021-02-16 23:31:55 +01:00
Patrik Svensson
17ee8990f4 Update example image 2021-02-15 13:01:30 +01:00
Bastian Eicher
a1050fc676 Handle output to stderr 2021-02-14 18:08:42 +01:00
Phil Scott
9312663bde Adds text and Progress bar spinner column for tasks yet to be started 2021-02-14 18:03:57 +01:00
Patrik Svensson
102e2dc38d Allow formatting breakdown charts with lambda expr
Relates to #252
2021-02-13 17:09:51 +01:00
Patrik Svensson
28e9c14de4 Register the console lazily in CLI type registrar
This should fix a strange bug we're seeing in Cake on macOS.
2021-02-12 02:04:59 +01:00
Patrik Svensson
fd217ffc83 Update sponsor text 2021-02-11 23:22:43 +01:00
Patrik Svensson
95ec04df40 Add sponsor information 2021-02-11 23:20:11 +01:00
Patrik Svensson
705cf745ea Add formatting support for breakdown chart values
Closes #252
2021-02-05 11:53:55 +01:00
Patrik Svensson
b64e016e8c Add breakdown chart support
This also cleans up the bar chart code slightly and fixes
some minor bugs that were detected in related code.

Closes #244
2021-02-01 01:03:39 +01:00
Patrik Svensson
58400fe74e Fix code generation
Previous changes introduced some bugs to the
code generation scripts and templates, which
now have been fixed.
2021-01-29 21:46:08 +01:00
Patrik Svensson
e20f6284f9 Clean up profile enrichment 2021-01-29 20:16:52 +01:00
David Butler
953008b5e3 Implemented buffer/stream constructors for CanvasImage (#246)
* Implemented buffer/stream constructors for CanvasImage and added section to Canvas example

Signed-off-by: David Butler <mail@davidbutlerdesign.co.uk>
2021-01-27 18:12:22 +01:00
Milosz Krajewski
ad49b6aa67 GH-242: Fix version retrieval for single file applications (#245) 2021-01-26 00:45:38 +01:00
Patrik Svensson
31a5e17a45 Remove InteractivityDetector 2021-01-19 18:12:15 +01:00
Patrik Svensson
f06dc7e7d8 GitHub actions should use default width (for now) 2021-01-19 18:12:15 +01:00
Patrik Svensson
a23bec4082 Add profile support
Closes #231
2021-01-19 17:53:03 +01:00
Patrik Svensson
913a7b1e37 Add support for default choice in selection prompt
Closes #234
2021-01-15 17:05:11 +01:00
Nick
63bae278a9 Add support for selection prompt highlighting 2021-01-15 15:23:09 +01:00
Eslami Sepehr
1a747696a8 Add Persian README 2021-01-15 09:08:37 +01:00
Matt Constable
994540d97f Add cycle detection to tree rendering 2021-01-14 18:37:22 +01:00
Thomas Freudenberg
dee3c01629 mask default value when prompt is a secret 2021-01-14 17:44:18 +01:00
Mattias Karlsson
a3e11b24e5 (GH-226) Switch ParameterValidationAttribute check to IsNullOrWhiteSpace
* fixes #226
2021-01-13 20:31:33 +01:00
Jay Turpin
35568ab823 Updated Commands with with new Execute() method signature 2021-01-13 19:48:15 +01:00
Patrik Svensson
07db28bb6f Add enhancements to progress widget
* Adds TransferSpeedColumn
* Adds DownloadedColumn
* Adds ElapsedTimeColumn
* Minor enhancements to existing columns
2021-01-12 14:10:07 +01:00
ριтєя мαяχ
d87d8e4422 Update exceptions.md 2021-01-10 20:45:44 +01:00
Patrik Svensson
a977fdadff Fix tree node collection type 2021-01-10 16:59:40 +01:00
Patrik Svensson
8261b25e5c Fix tree rendering
Fixes some tree rendering problems where lines were not properly drawn
at some levels during some circumstances.

* Change the API back to only allow one root.
* Now uses a stack based approach to rendering instead of recursion.
* Removes the need for measuring the whole tree in advance.
  Leave this up to each child to render.
2021-01-10 15:55:11 +01:00
Patrik Svensson
0e0f4b4220 Add interactive prompts for selecting values
* Adds SelectionPrompt
* Adds MultiSelectionPrompt

Closes #210
2021-01-09 09:37:28 +01:00
Patrik Svensson
3a593857c8 Add progress and status result overloads 2021-01-06 09:54:45 +01:00
Patrik Svensson
11e192e750 Update Canvas tests 2021-01-06 09:54:45 +01:00
Thomas Freudenberg
8901450283 Allow returning a result from Progress.StartAsync/Status.StartAsync 2021-01-06 08:08:38 +01:00
Patrik Svensson
0796bad598 Add contributing guidelines 2021-01-05 14:38:29 +01:00
Matt Constable
5b553a4106 Added canvas unit tests & fix canvas scaling bug 2021-01-05 14:00:04 +01:00
Patrik Svensson
1bb0b9ccc6 Fix expectation structure 2021-01-05 11:09:35 +01:00
Matt Constable
9ad5f2daeb Fix console detection for Cygwin/WSL-Shell on Windows 2021-01-04 18:24:56 +01:00
Patrik Svensson
1f211d3e1f Add convenience methods for tree nodes 2021-01-03 23:28:55 +01:00
Patrik Svensson
87e6b42409 Add tree example 2021-01-03 23:28:55 +01:00
Patrik Svensson
1aa958ced3 Add support for multiple tree roots 2021-01-03 23:28:55 +01:00
Patrik Svensson
4bfb24bfcb Streamline tree API a bit 2021-01-03 23:28:55 +01:00
Matt Constable
b136d0299b Add tree widget 2021-01-02 10:01:16 +01:00
Patrik Svensson
179e243214 Clean up table rendering a bit 2021-01-02 09:33:22 +01:00
Patrik Svensson
c6210f75ca Prevent endless loop in tokenization
Closes #198
2021-01-01 23:01:51 +01:00
Patrik Svensson
b81739567b Fix argument order in help
Closes #188
2021-01-01 13:43:28 +01:00
Patrik Svensson
5cf41725a5 Do not split remaining args on space
Closes #186
2021-01-01 12:19:37 +01:00
Matthew Constable
f561d71e4e Remove unused Segment.TruncateWithEllipsis method 2020-12-31 17:29:50 +01:00
Simon Cropp
e71db7f78c fix some nullability issues 2020-12-31 11:09:03 +01:00
Patrik Svensson
79742ce9e3 Parse quoted strings correctly
When parsing quoted strings, space was not handled
properly in remaining arguments.

Fixes #186
2020-12-30 18:43:29 +01:00
Patrik Svensson
241423dd16 Do not truncate command table
Temporary fix for commands not showing up if they
are missing a description. This is really a bug in the table
rendering and should be fixed there at some point.

Closes #192
2020-12-30 18:43:29 +01:00
Patrik Svensson
4e2251fd62 Add migration guide for Spectre.Cli 2020-12-29 10:29:26 +01:00
Patrik Svensson
0ae419326d Add Spectre.Cli to Spectre.Console
* Renames Spectre.Cli to Spectre.Console.Cli.
* Now uses Verify with Spectre.Console.Cli tests.
* Removes some duplicate definitions.

Closes #168
2020-12-28 17:28:03 +01:00
Thomas Freudenberg
0bbf9b81a9 Adds optional function to get the display string for TextPrompt choices 2020-12-26 18:17:46 +01:00
Simon Cropp
041aea2ae5 spelling 2020-12-26 18:16:41 +01:00
Simon Cropp
f417e297cd update test refs
the latest of shouldy has better nullable attributes
2020-12-26 18:13:35 +01:00
Simon Cropp
5045b8b959 remove pdb AllowedOutputExtensionsInPackageBuildOutputFolder 2020-12-26 18:12:19 +01:00
Patrik Svensson
7dccb310f3 Add support for bar charts
Closes #103
2020-12-23 10:05:08 +01:00
Patrik Svensson
1cf30f62fc Add autocomplete for text prompt
Closes #166
2020-12-22 11:31:22 +01:00
Patrik Svensson
e280b82679 Fix dividing with infinity bug
When calculating the remaining time for a progress task,
we divide the value delta with the current speed.
If the speed is zero, then the resulting double will
be 'infinity' which will lead to TimeSpan.FromSeconds
throwing.

This commit fixes that bug by setting the speed to 1
if it's 0 when calculating the remaining time.

Closes #169
2020-12-17 00:43:47 +01:00
Patrik Svensson
6932c95731 Fix bug when splitting text containing CJK chars
In Segment.Split, we didn't take cell width into account
when calculating the offset, which resulted in some "fun" bugs.
I've added a new overload for Segment.Split and obsoleted the old one.

Closes #150
2020-12-17 00:02:00 +01:00
Patrik Svensson
ee305702e8 Update issue templates 2020-12-14 10:36:05 +01:00
Patrik Svensson
63abcc92ba Set max value for progress task properly
Also clamp the task value if it's greater than the max value.

Closes #163
2020-12-12 17:29:07 +01:00
Patrik Svensson
acf01e056f Clean up status related code a bit 2020-12-09 08:37:32 +01:00
Patrik Svensson
501db5d287 Add status support 2020-12-09 00:07:02 +01:00
Patrik Svensson
cbed41e637 Add support for different spinners 2020-12-06 15:41:45 +01:00
Patrik Svensson
3c504155bc Fix progress rendering bug 2020-12-04 10:19:09 +01:00
Patrik Svensson
ae32785f21 Add progress task list support 2020-12-04 07:29:48 +01:00
chenxuuu
c61e386440 Add Chinese README 2020-11-30 05:56:25 +01:00
Patrik Svensson
b7cd7dd53e Fix grammar in Canvas Image docs 2020-11-25 13:52:17 +01:00
Patrik Svensson
3e1251b86a Fix heading size 2020-11-25 13:41:11 +01:00
Patrik Svensson
01fdbac51e Fix typo in package description 2020-11-25 12:16:26 +01:00
Patrik Svensson
b0b988a1e7 Add Canvas and CanvasImage docs 2020-11-25 12:15:25 +01:00
Patrik Svensson
2a9fa223de Add canvas and image support
Adds support for drawing "pixels" and displaying
images in the terminal.
2020-11-25 10:07:34 +01:00
Patrik Svensson
4f6eca4fcb Fix rendering of exceptions with generic params
Closes #145
2020-11-24 22:16:17 +01:00
Patrik Svensson
a5125d640c Add initial FIGlet docs 2020-11-22 03:27:15 +01:00
Patrik Svensson
a59e0dcb21 Add FIGlet text support
Closes #97
2020-11-22 03:09:42 +01:00
Simon Cropp
bde61cc6ff Verify: Use custom test directory 2020-11-20 23:27:35 +01:00
Simon Cropp
5c33b87a9c Add Verify for testing 2020-11-20 16:22:23 +01:00
Patrik Svensson
aaf77c3b25 Fix prompt example docs 2020-11-19 14:46:43 +01:00
Patrik Svensson
d70ad661fc Add docs for text prompts 2020-11-19 14:25:24 +01:00
Patrik Svensson
0d209d8f18 Add text prompt support 2020-11-19 12:24:04 +01:00
Patrik Svensson
380c6aca45 Add net5.0 target framework 2020-11-11 15:28:32 +01:00
Patrik Svensson
b1da5e7ba8 Add support for markup text in panel header 2020-11-07 20:43:53 +01:00
Patrik Svensson
be3350a411 Bump dotnet-example to 1.0.0 2020-11-03 18:14:41 +01:00
Patrik Svensson
a1d11e9d0c Add support for moving the cursor 2020-10-28 18:57:08 +01:00
Patrik Svensson
93d1971f48 Update rule example and docs 2020-10-27 17:30:50 +01:00
Martin Andersen
bca1c889d1 Add Padding extension
Add extension method for specifying horizontal and vertical padding.
Similar constructor for `Padding` already existed.

Update documentation for table column appearance (padding).

Update
`Should_Render_Padded_Object_Correctly_When_Nested_Within_Other_Object`
test to use new extension method.
2020-10-27 09:09:30 +01:00
Takahito Yamatoya
9915a0d6a8 Update Documentation for escape 2020-10-27 09:08:27 +01:00
Takahito Yamatoya
f34fc43d00 Update documentation for aligning tables 2020-10-27 09:08:27 +01:00
Patrik Svensson
e7f497050c Add row and column accessors for tables and grids 2020-10-26 18:15:27 +01:00
Martin Andersen
3e5e22d6c2 Update documentation
- ExceptionFormat -> ExceptionFormats.
- Fix link to documentation.
- Add cross reference to Styles.
- Render table in example code.
- Add code for setting background color.
2020-10-26 15:31:44 +01:00
Patrik Svensson
10daf727e9 Fix outdated documentation 2020-10-26 12:20:17 +01:00
Patrik Svensson
03334f693d Add support for table footers 2020-10-26 00:01:13 +01:00
Patrik Svensson
c9c0ad733f Fix rendering bug when splitting lines
The bug might occur if there are wide characters such as emojis
at the end of a line. The SplitLines method mixed cell width
and text length, which might give incorrect results. This commit
makes sure that comparison and calculation is done using cell width
where it's appropriate.
2020-10-24 01:45:41 +02:00
Patrik Svensson
041bd016a2 Remove verbs from extension methods
Removed the verbs from all extension methods that manipulate
properties which makes the API more succinct and easier to read.

Also added implicit conversion from string to Style.

As a good OSS citizen, I've obsoleted the old methods with
a warning for now, so this shouldn't break anyone using
the old methods.
2020-10-23 15:08:18 +02:00
Takahito Yamatoya
037a215a78 Add documentation for rule 2020-10-22 08:53:20 +02:00
Patrik Svensson
9afc1ea721 Add support for aligning tables 2020-10-21 18:15:51 +02:00
Takahito Yamatoya
b52056ee49 Update documentation for calendar 2020-10-20 21:55:29 +02:00
Patrik Svensson
3941fd81ab Move table and calendar docs 2020-10-20 02:32:04 +02:00
Patrik Svensson
5a1b8a1710 Add rule widget
Adds a new rule widget.
Also fixes some bugs I encountered while testing
some unrelated things in an extremely small console.
2020-10-20 01:45:53 +02:00
Patrik Svensson
1410cba6c5 Add Markdown.Escape method 2020-10-20 01:09:26 +02:00
Patrik Svensson
70fc14e9cd Add new ctors for Rows and Columns widgets 2020-10-19 21:25:28 +02:00
Takahito Yamatoya
0b4359a52a Add installation instructions
* to add how to install

* fix

* remove empty line
2020-10-19 16:50:54 +02:00
Patrik Svensson
cb2924a609 Add table heading and footnote support
Closes #116
2020-10-19 15:46:57 +02:00
Takahito Yamatoya
5c119ee0c3 Add documentation for calendar 2020-10-19 15:44:16 +02:00
Takahito Yamatoya
b9d182b6e3 Add README.jp.md 2020-10-19 15:42:33 +02:00
Patrik Svensson
bfffef630f Do not draw tables that can't be drawn
This is a temporary fix for undrawable tables until we've
implemented a proper strategy. What this does is that it replaces
an undrawable table with an ellipsis (...). This should only
occur in either super big tables or deeply nested tables in a
console with a small buffer width.
2020-10-18 08:03:40 +02:00
Takahito Yamatoya
a2f507e58f update sample output 2020-10-18 06:56:47 +02:00
Takahito Yamatoya
d1d06d6a6b fix incorrect command 2020-10-18 06:56:47 +02:00
Patrik Svensson
52718c499c Fix minor typo in example 2020-10-17 13:22:01 +02:00
Patrik Svensson
7ef1ac483a Fix overflow splitting bug
Closes #93
2020-10-17 12:37:20 +02:00
Takahito Yamatoya
c0875c912a fix incorrect link 2020-10-17 12:16:18 +02:00
Patrik Svensson
3f2ca49071 Add calendar control
Closes #101
2020-10-16 23:02:53 +02:00
Khalid Abuhakmeh
0a0380ae0a Don't throw when console is small
this just returns an empty collection when
take is 0. It leads to some strange output, but
it doesn't blow up.

 #93
2020-10-08 22:17:12 +02:00
Patrik Svensson
ae92c606bb Add support for remapping emojis
Closes #94
2020-10-07 17:33:05 +02:00
Patrik Svensson
68e92f3365 Add various exception improvements 2020-10-07 11:57:28 +02:00
Patrik Svensson
39a8588dc3 Rename ExceptionFormats.None 2020-10-07 11:57:28 +02:00
Patrik Svensson
3c3afe7439 Add support for rendering exceptions 2020-10-05 07:03:02 +02:00
Gary Ewan Park
971f9032ba (doc) Dynamically generate sections
Rather than hard-coding them.  Then, as the number of sections increase,
no additional changes will be required here.
2020-10-03 16:30:21 +02:00
Gary Ewan Park
5149557560 (doc) Remove hard-coded link
Rather than specifying spectre.console directly in the layout, figure out
the URL using GetLink method.
2020-10-03 16:30:21 +02:00
Khalid Abuhakmeh
e0947708c9 Generalized Search
Generalized the search to work with any table
with some basic classes and some updated
JavaScript, we can now search colors and emojis.
2020-10-02 19:39:02 +02:00
Patrik Svensson
b1db8a9403 Clean up border code
Removed caching that really didn't do anything anymore.
2020-10-01 23:05:02 +02:00
Khalid Abuhakmeh
a2f8652575 Add Search To Emoji Page
This adds a typeahead search feature
for the very large emoji table. It filters as you type to find if an emoji exists or not.

The JavaScript could be adapted to work on all tables in the future.
2020-10-01 22:00:39 +02:00
Khalid Abuhakmeh
672faa131f Update Docs Readme
Added some more context to the docs readme for
folks looking to contribute. Also added the license
so its clear what the license of the docs site is. As
a small tweak I removed a duplicate string value and
use the Constant.
2020-10-01 20:51:32 +02:00
Patrik Svensson
e429f6434b Update examples 2020-10-01 14:43:08 +02:00
Patrik Svensson
93ec7401c8 Add support for markdown tables
Closes #85

* Split Border into BoxBorder and TableBorder
* Change how different table parts are composed
* Add markdown table border
2020-10-01 14:43:08 +02:00
Patrik Svensson
697273917e Move console encoder to rendering namespace 2020-09-21 17:07:05 +02:00
Patrik Svensson
2943535973 Make segments immutable 2020-09-21 17:03:17 +02:00
Patrik Svensson
cd0d182f12 Add support for recording console output
This commit adds support for recording console output
as well as exporting it to either text or HTML. A user can
also provide their own encoder if they wish.
2020-09-21 13:33:28 +02:00
Patrik Svensson
b197f278ed Add support for rows
Closes #69
2020-09-20 19:17:33 +02:00
Patrik Svensson
3847a8949f Fix bug with uris being interpreted as emojis
Closes #82
2020-09-20 13:00:44 +02:00
Patrik Svensson
eeb3f967b6 Update emoji support
* Add constants for emojis
* Move emoji shortcode rendering to Markup
* Add documentation
* Add example
* Add tests
2020-09-18 16:11:51 +02:00
Patrik Svensson
090b30f731 Use Wcwidth library 2020-09-18 15:31:12 +02:00
Patrik Svensson
df291ef84e Fix Info example emoji problem
The emojis that previously were used, used Unicode combinators
which are not fully supported. Changing to :thumbs_up: and :thumbs_down:
instead.
2020-09-17 10:58:50 +02:00
Patrik Svensson
7d6104ace4 Add padder widget
This commit adds a padder can be use to pad other IRenderable
objects such as tables, panels, grids, text, etc.
2020-09-17 10:58:50 +02:00
Kristian Hellang
314456ca17 Add emoji codes to example 2020-09-17 10:35:15 +02:00
Kristian Hellang
b7f654cd7f Replace emoji in segment text 2020-09-17 10:35:15 +02:00
Kristian Hellang
fea8a36e8a Add generated Emoji class with corresponding non-generated file 2020-09-17 10:35:15 +02:00
Kristian Hellang
0632b38477 Fix relative path in existing color script 2020-09-17 10:35:15 +02:00
Kristian Hellang
a7b7d4e556 Add Generator command to generate emoji lookup table 2020-09-17 10:35:15 +02:00
Kristian Hellang
11d331e31d Add .DS_Store to .gitignore 2020-09-17 10:35:15 +02:00
Patrik Svensson
ce670a7ca9 Add link identity generator 2020-09-12 14:47:32 +02:00
Patrik Svensson
101e244059 Minor clean up 2020-09-12 10:46:57 +02:00
Patrik Svensson
504746c5dc Add link support for supported terminals
Also refactors the code quite a bit, to make it a bit more
easier to add features like this in the future.

Closes #75
2020-09-11 17:44:56 +02:00
Patrik Svensson
1601ef24b3 Update border documentation 2020-09-09 14:27:40 +02:00
Patrik Svensson
b46d0fa4f6 Group IAnsiConsole extensions in csproj 2020-09-09 08:47:55 +02:00
Patrik Svensson
4f06687104 Restructure solution a bit 2020-09-09 08:43:48 +02:00
Patrik Svensson
003e15686f Add documentation for tables
Also moves "Colors" and "Styles" sections to appendix.
2020-09-08 18:21:52 +02:00
Patrik Svensson
3e9796849b Add more borders for grids, tables, and panels
* Ascii2
* AsciiDoubleHead
* Double
* DoubleEdge
* Heavy
* HeavyEdge
* HeavyHead
* Horizontal
* Minimal
* MinimalDoubleHead
* MinimalHeavyHead
* Simple
* SimpleHeavy
2020-09-08 00:16:20 +02:00
Patrik Svensson
3cc19520b0 Add implicit conversion op from string to Style
Closes #71
2020-09-06 23:03:51 +02:00
Patrik Svensson
87bde3e5a2 Remove BorderKind in favour of Border 2020-09-06 12:29:48 +02:00
Patrik Svensson
e6e9a4d950 Add description for 'Info' example 2020-09-05 08:52:06 +02:00
Patrik Svensson
29ce14e1e8 Rename 'Diagnostic' example to 'Info' 2020-09-05 08:50:00 +02:00
Patrik Svensson
ceb3572d6a Make table and grid extension methods fluent 2020-09-05 08:49:36 +02:00
Patrik Svensson
13c56eca01 Allow mutation of segments 2020-09-05 08:39:48 +02:00
Patrik Svensson
a477884d36 Move Panel extensions to Spectre.Console namespace 2020-09-05 08:20:13 +02:00
Patrik Svensson
ae6d2c63a3 Add column support
Adds support for rendering arbitrary data into columns.

Closes #67
2020-09-05 07:45:38 +02:00
Patrik Svensson
e946289bd9 Make styles composable
Also adds some new extension methods and make some APIs a bit more consistent.

Closes #64
2020-09-03 21:26:20 +02:00
Patrik Svensson
bcaaa6b2d3 Update table of contents (skip-ci) 2020-09-03 20:04:06 +02:00
Patrik Svensson
d3588a4b06 Remove styles and colors (skip-ci) 2020-09-03 20:03:26 +02:00
Patrik Svensson
7471e9d38c Add panel header support
Closes #63
2020-09-03 19:02:29 +02:00
Patrik Svensson
9f8ca6d648 Add text overflow support
Closes #61
2020-09-03 14:57:57 +02:00
Patrik Svensson
88edfe68ec Add border for color representations 2020-09-02 09:55:44 +02:00
Patrik Svensson
5d32764a64 Fix typo: SRG -> SGR 2020-09-02 09:02:59 +02:00
Patrik Svensson
4f6c9c62c7 Set fetch depth to 0 2020-09-01 22:05:46 +02:00
Patrik Svensson
f2677213a4 Separate build and run when publishing docs 2020-09-01 22:00:44 +02:00
Patrik Svensson
bdaf00a556 Remove empty documentation pages 2020-09-01 21:51:25 +02:00
Patrik Svensson
7de4b6c7b9 Build docs as part of CI 2020-09-01 21:50:36 +02:00
Patrik Svensson
0bc801e3eb Build docs when source change 2020-09-01 21:40:49 +02:00
Patrik Svensson
88a82cdad0 Build docs in release mode 2020-09-01 21:39:40 +02:00
Patrik Svensson
0cecb555d5 Show documentation version in footer 2020-09-01 21:33:15 +02:00
Patrik Svensson
52e3ee17b0 Fix logo link 2020-09-01 21:28:52 +02:00
Dave Glick
caf7661e66 Moves all the pages up a level and hardcodes the section name 2020-09-01 21:23:01 +02:00
Dave Glick
65f0a085cc Updated to the latest Statiq Web with breakage fixes 2020-09-01 21:03:47 +02:00
Patrik Svensson
a123806cd8 Add docs for escaping [ and ] in markup 2020-09-01 16:52:40 +02:00
Patrik Svensson
173645cdd2 Added documentation for markup text 2020-08-31 14:05:28 +02:00
Patrik Svensson
7fd2efaeb5 Merge segments before rendering
This will reduce the number of segments to render
and produce cleaner ANSI escape code sequences.

Closes #46
2020-08-30 12:40:34 +02:00
Patrik Svensson
47fd646d21 Enable publish for all tags (skip-ci) 2020-08-30 10:22:53 +02:00
Patrik Svensson
a06859dcb5 Only publish on tags (skip-ci) 2020-08-30 10:12:53 +02:00
Patrik Svensson
7d3a67e6ae Always publish tags (skip-ci) 2020-08-30 10:04:29 +02:00
Patrik Svensson
f4497b1278 Docs: Added color number (skip-ci) 2020-08-29 11:25:19 +02:00
Patrik Svensson
a16daade6c Fallback to default buffer size
Also fixes a bug when using Spectre.Console in GitHub Actions.
2020-08-28 11:56:54 +02:00
Khalid Abuhakmeh
ab73d16583 Fix Unescaped Bracket
Was throwing error because of unescaped end bracket
at the end of options.
2020-08-27 20:53:10 +02:00
Patrik Svensson
f2566f2ca4 Remove commented out code (skip-ci) 2020-08-27 20:13:35 +02:00
Patrik Svensson
358b0225b4 Add documentation header (skip-ci) 2020-08-27 20:12:13 +02:00
950 changed files with 66685 additions and 5295 deletions

28
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,28 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Information**
- OS: [eg Windows/Linux/MacOS]
- Version: [e.g. 0.33.0]
- Terminal: [e.g Windows Terminal]
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -6,6 +6,35 @@ env:
DOTNET_CLI_TELEMETRY_OPTOUT: true
jobs:
###################################################
# DOCS
###################################################
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
- name: Build
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd docs
dotnet run --configuration Release
###################################################
# BUILD
###################################################
build:
name: Build
if: "!contains(github.event.head_commit.message, 'skip-ci')"
@@ -26,13 +55,32 @@ jobs:
with:
fetch-depth: 0
- name: Setup dotnet
- name: Setup dotnet 3.1.402
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.301
dotnet-version: 3.1.402
- name: Setup dotnet 5.0.100
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
- name: Integration Tests
shell: bash
run: |
dotnet tool restore
dotnet example --all
- name: Build
shell: bash
run: |
dotnet tool restore
dotnet cake
dotnet cake
- name: Upload Verify Test Results
if: failure()
uses: actions/upload-artifact@v2
with:
name: verify-test-results
path: |
**/*.received.*

View File

@@ -4,19 +4,27 @@ on:
push:
paths:
- 'docs/**'
- 'src/**'
jobs:
###################################################
# DOCS
###################################################
build:
name: Deploy
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@master
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.301' # SDK Version to use.
dotnet-version: 5.0.202
- name: Publish
shell: bash
@@ -24,4 +32,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd docs
dotnet run -- deploy
dotnet run --configuration Release -- deploy

View File

@@ -6,6 +6,8 @@ on:
- '*'
branches:
- main
paths:
- 'src/**'
env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
@@ -13,13 +15,38 @@ env:
jobs:
###################################################
# DOCS
###################################################
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
- name: Build
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd docs
dotnet run --configuration Release
###################################################
# BUILD
###################################################
build:
name: Build
if: "!contains(github.event.head_commit.message, 'skip-ci')"
needs: [docs]
if: "!contains(github.event.head_commit.message, 'skip-ci') || startsWith(github.ref, 'refs/tags/')"
strategy:
matrix:
kind: ['linux', 'windows', 'macOS']
@@ -37,10 +64,15 @@ jobs:
with:
fetch-depth: 0
- name: Setup dotnet
- name: Setup dotnet 3.1.402
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.301
dotnet-version: 3.1.402
- name: Setup dotnet 5.0.100
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
- name: Build
shell: bash
@@ -55,7 +87,7 @@ jobs:
publish:
name: Publish
needs: [build]
if: "!contains(github.event.head_commit.message, 'skip-ci')"
if: "!contains(github.event.head_commit.message, 'skip-ci') || startsWith(github.ref, 'refs/tags/')"
runs-on: ubuntu-latest
steps:
- name: Checkout
@@ -63,10 +95,15 @@ jobs:
with:
fetch-depth: 0
- name: Setup dotnet
- name: Setup dotnet 3.1.402
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.301
dotnet-version: 3.1.402
- name: Setup dotnet 5.0.100
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.202
- name: Publish
shell: bash

5
.gitignore vendored
View File

@@ -5,6 +5,8 @@
[Pp]ackages/
/.artifacts/
/[Tt]ools/
.idea
.DS_Store
# Cakeup
cakeup-x86_64-latest.exe
@@ -77,7 +79,6 @@ x64/
_ReSharper*
# NCrunch
*.ncrunch*
.*crunch*.local.xml
_NCrunch_*
@@ -86,3 +87,5 @@ packages
# Windows
Thumbs.db
*.received.*

161
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,161 @@
# Contribution Guidelines
* [Prerequisites](#prerequisites)
* [Definition of trivial contributions](#definition-of-trivial-contributions)
* [Code](#code)
* [Code style](#code-style)
* [Dependencies](#dependencies)
* [Unit tests](#unit-tests)
* [Contributing process](#contributing-process)
* [Get buyoff or find open community issues or features](#get-buyoff-or-find-open-community-issues-or-features)
* [Set up your environment](#Set-up-your-environment)
* [Prepare commits](#prepare-commits)
* [Submit pull request](#Submit-pull-request)
* [Respond to feedback on pull request](#respond-to-feedback-on-pull-request)
* [Other general information](#other-general-information)
* [Acknowledgement](#acknowledgement)
## Prerequisites
By contributing to Spectre.Console, you assert that:
* The contribution is your own original work.
* You have the right to assign the copyright for the work (it is not owned by your employer, or
you have been given copyright assignment in writing).
* You [license](https://github.com/spectreconsole/spectre.console/blob/main/LICENSE) the contribution under the terms applied to the rest of the Spectre.Console project.
* You agree to follow the [code of conduct](https://github.com/spectreconsole/spectre.console/blob/main/CODE_OF_CONDUCT.md).
## Definition of trivial contributions
It's hard to define what is a trivial contribution. Sometimes even a 1 character change can be considered significant.
Unfortunately because it can be subjective, the decision on what is trivial comes from the maintainers of the project
and not from folks contributing to the project.
What is generally considered trivial:
* Fixing a typo.
* Documentation changes.
## Code
### Code style
Normal .NET coding guidelines apply.
See the [Framework Design Guidelines](https://msdn.microsoft.com/en-us/library/ms229042%28v=vs.110%29.aspx) for more information.
### Dependencies
The assembly `Spectre.Console` should have no dependencies except the .NET BCL library.
### Unit tests
Make sure to run all unit tests before creating a pull request.
Any new code should also have reasonable unit test coverage.
## Contributing process
### Get buyoff or find open community issues or features
* Through GitHub, or through the [GitHub discussions](https://github.com/spectreconsole/spectre.console/discussions) (preferred),
you talk about a feature you would like to see (or a bug), and why it should be in Spectre.Console.
* If approved through the GitHub discussions, ensure an accompanying GitHub issue is created with
information and a link back to the discussion.
* Once you get a nod from someone in the Spectre.Console Team, you can start on the feature.
* Alternatively, if a feature is on the issues list with the
[Up For Grabs](https://github.com/spectreconsole/spectre.console/labels/up-for-grabs) label,
it is open for a community member (contributor) to patch. You should comment that you are signing up for it on
the issue so someone else doesn't also sign up for the work.
### Set up your environment
* You create, or update, a fork of `spectreconsole/spectre.console` under your GitHub account.
* From there you create a branch named specific to the feature.
* In the branch you do work specific to the feature.
* Please also observe the following:
* No reformatting
* No changing files that are not specific to the feature.
* More covered below in the **Prepare commits** section.
* Test your changes and please help us out by updating and implementing some automated tests.
It is recommended that all contributors spend some time looking over the tests in the source code.
You can't go wrong emulating one of the existing tests and then changing it specific to the behavior you are testing.
* Please do not update your branch from the main branch unless we ask you to. See the responding to feedback section below.
### Prepare commits
This section serves to help you understand what makes a good commit.
A commit should observe the following:
* A commit is a small logical unit that represents a change.
* Should include new or changed tests relevant to the changes you are making.
* No unnecessary whitespace. Check for whitespace with `git diff --check` and `git diff --cached --check` before commit.
* You can stage parts of a file for commit.
### Submit pull request
Prerequisites:
* You are making commits in a feature branch.
* All code should compile without errors or warnings.
* All tests should be passing.
Submitting PR:
* Once you feel it is ready, submit the pull request to the `spectreconsole/spectre.console` repository against the `main` branch
unless specifically requested to submit it against another branch.
* In the case of a larger change that is going to require more discussion,
please submit a PR sooner. Waiting until you are ready may mean more changes than you are
interested in if the changes are taking things in a direction the maintainers do not want to go.
* In the pull request, outline what you did and point to specific conversations (as in URLs)
and issues that you are resolving. This is a tremendous help for us in evaluation and acceptance.
* Once the pull request is in, please do not delete the branch or close the pull request
(unless something is wrong with it).
* One of the Spectre.Console team members, or one of the maintainers, will evaluate it within a
reasonable time period (which is to say usually within 1-3 weeks). Some things get evaluated
faster or fast tracked. We are human and we have active lives outside of open source so don't
fret if you haven't seen any activity on your pull request within a month or two.
We don't have a Service Level Agreement (SLA) for pull requests.
Just know that we will evaluate your pull request.
### Respond to feedback on pull request
We may have feedback for you to fix or change some things. We generally like to see that pushed against
the same topic branch (it will automatically update the Pull Request). You can also fix/squash/rebase
commits and push the same topic branch with `--force` (it's generally acceptable to do this on topic
branches not in the main repository, it is generally unacceptable and should be avoided at all costs
against the main repository).
If we have comments or questions when we do evaluate it and receive no response, it will probably
lessen the chance of getting accepted. Eventually, this means it will be closed if it is not accepted.
Please know this doesn't mean we don't value your contribution, just that things go stale. If in the
future you want to pick it back up, feel free to address our concerns/questions/feedback and reopen
the issue/open a new PR (referencing old one).
Sometimes we may need you to rebase your commit against the latest code before we can review it further.
If this happens, you can do the following:
* `git fetch upstream` (upstream remote would be `spectreconsole/spectre.console`)
* `git checkout main`
* `git rebase upstream/main`
* `git checkout your-branch`
* `git rebase main`
* Fix any merge conflicts
* `git push origin your-branch` (origin would be your GitHub repo or `your-github-username/spectre.console` in this case).
You may need to `git push origin your-branch --force` to get the commits pushed.
This is generally acceptable with topic branches not in the mainstream repository.
The only reasons a pull request should be closed and resubmitted are as follows:
* When the pull request is targeting the wrong branch (this doesn't happen as often).
* When there are updates made to the original by someone other than the original contributor.
Then the old branch is closed with a note on the newer branch this supersedes #github_number.
## Other general information
If you reformat code or hit core functionality without an approval from a person on the Spectre.Console Team,
it's likely that no matter how awesome it looks afterwards, it will probably not get accepted.
Reformatting code makes it harder for us to evaluate exactly what was changed.
If you do these things, it will be make evaluation and acceptance easy.
Now if you stray outside of the guidelines we have above, it doesn't mean we are going to ignore
your pull request. It will just make things harder for us.
Harder for us roughly translates to a longer SLA for your pull request.
## Acknowledgement
This contribution guide was taken from the [Chocolatey project](https://chocolatey.org/)
with permission and was edited to follow Spectre.Console's conventions and processes.

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 Spectre Systems AB
Copyright (c) 2020 Patrik Svensson, Phil Scott
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

6
NuGet.Config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>

77
README.fa.md Normal file
View File

@@ -0,0 +1,77 @@
# `Spectre.Console`
_[![Spectre.Console NuGet Version](https://img.shields.io/nuget/v/spectre.console.svg?style=flat&label=NuGet%3A%20Spectre.Console)](https://www.nuget.org/packages/spectre.console)_
<div dir="rtl">
یک کتابخانه NET Standard 2.0/.NET 5. که ایجاد Console Applicationهای زیبا و cross platform را آسان‌تر می‌کند.
از کتابخانه عالی [Rich](https://github.com/willmcgugan/rich) برای پایتون، بسیار الهام گرفته شده است.
## فهرست
1. [امکانات](#features)
2. [نصب](#installing)
3. [مستندات](#documentation)
4. [مثال‌ها](#examples)
5. [مجوز](#license)
<h2 id="features">امکانات</h2>
* با در نظر گرفتن تست واحد نوشته شده است.
* جداول، چارچوب‌ها، پنل‌ها و یک زبان نشانه گذاری که از [rich](https://github.com/willmcgugan/rich) الهام گرفته شده است را پشتیبانی می‌کند.
* از رایج ترین پارامترهای SRG در هنگام فرم دهی متن مانند پررنگ، کم نور، اریب، زیرخط، خط زدن و چشمک زدن پشتیبانی می‌کند.
* پشتیبانی از رنگ‌های 28/8/4/3-بیت در ترمینال.
این کتابخانه توانایی ترمینال فعلی را تشخیص داده و در صورت لزوم رنگ‌ها را کاهش می‌دهد.
![Example](docs/input/assets/images/example.png)
<h2 id="installing">نصب</h2>
سریع ترین راه برای شروع `Spectre.Console` نصب از طریق NuGet Package می‌باشد.
<pre dir="ltr">
dotnet add package Spectre.Console
</pre>
<h2 id="documentation">مستندات</h2>
مستندات `Spectre.Console` را در اینجا می‌توایند پیدا کنید:
<div dir="ltr">
https://spectreconsole.net/
</div>
<h2 id="examples">مثال‌ها</h2>
برای بررسی `Spectre.Console` در عمل، ابزار سراسری
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
را نصب کنید.
<pre dir="ltr">
> dotnet tool restore
</pre>
حالا شما می‌توانید مثال‌های موجود در این مخزن را لیست کنید:
<pre dir="ltr">
> dotnet example
</pre>
و برای اجرای مثال:
<pre dir="ltr">
> dotnet example tables
</pre>
<h2 id="license">مجوز</h2>
<div dir="ltr">
Copyright © Patrik Svensson, Phil Scott
</div>
همانطور که Spectre.Console تحت مجوز MIT ارائه شده است؛ برای کسب اطلاعات بیشتر به مجوز مراجعه کنید.
* برای SixLabors.ImageSharp، مشاهده کنید: https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
</div>

414
README.jp.md Normal file
View File

@@ -0,0 +1,414 @@
# `Spectre.Console`
_[![Spectre.Console NuGet Version](https://img.shields.io/nuget/v/spectre.console.svg?style=flat&label=NuGet%3A%20Spectre.Console)](https://www.nuget.org/packages/spectre.console)_
綺麗なコンソールアプリケーションを簡単に作成するための.NET Standard 2.0ライブラリです。
Python用の素晴らしい[Rich ライブラリ](https://github.com/willmcgugan/rich)に強く影響を受けています。
## 目次
1. [特徴](#特徴)
2. [](#例)
3. [使用方法](#使用方法)
3.1. [Static APIの利用](#static-apiの利用)
3.2. [コンソールの作成](#コンソールの作成)
4. [例の実行](#例の実行)
5. [クイックスタート](#クイックスタート)
6. [マークアップ](#マークアップ)
7. [絵文字](#絵文字)
8. [テーブル](#テーブル)
9. [例外](#例外)
## 特徴
* ユニットテストを意識して書いています。
* table、grid、panel、マークアップ言語に影響を受けた [rich](https://github.com/willmcgugan/rich) に対応しています。
* 太字、薄字、斜字、下線、斜線、点滅などの一般的なSGR parameters に対応しています。
* ターミナルで 3/4/8/24ビットカラーに対応しています。
ライブラリは現在のターミナルの性能を検知し、必要なカラーにダウングレードします
## 例
![Example](docs/input/assets/images/example.png)
## 使用方法
`Spectre.Console` APIはステートフルで、スレッドセーフではありません。
異なるスレッドからコンソールに書く必要がある場合、通常の`System.Console` APIを使用するときと同様、適切な注意を払ってください。
現在の端末がANSIエスケープシーケンスに対応していない場合、
`Spectre.Console`は、`System.Console` APIの利用に切り替わります。
_メモ: このライブラリは現在開発中で、APIは1.0のリリースまでの間に変更されたり、
削除されたりする可能性があります。_
### Static APIの利用
`System.Console` APIでするように、テキストを出力したいだけの時にはstatic APIが最適ですが、綺麗です。
```csharp
AnsiConsole.Foreground = Color.CornflowerBlue;
AnsiConsole.Decoration = Decoration.Underline | Decoration.Bold;
AnsiConsole.WriteLine("Hello World!");
AnsiConsole.Reset();
AnsiConsole.MarkupLine("[bold yellow on red]{0}[/] [underline]world[/]!", "Goodbye");
```
もし、デフォルトの`IAnsiConsole`への参照を取得したい場合、
`AnsiConsole.Console`経由でアクセスできます。
### コンソールの作成
単体テスト中にコードの実行環境を制御したい場合など、
特定の機能をもつコンソールを明示的に作成すると便利なことがあります。
単体テストの一部としてコードで `AnsiConsole`を使わないことを推奨します。
```csharp
IAnsiConsole console = AnsiConsole.Create(
new AnsiConsoleSettings()
{
Ansi = AnsiSupport.Yes,
ColorSystem = ColorSystemSupport.TrueColor,
Out = new StringWriter(),
});
```
_メモ: 主導でコンソールを作成しているときに特定のカラーシステムを指定できたとしても、
ユーザーのターミナルでは使えないかもしれないことを覚えておいてください。
テスト用にIAnsiConsoleを作成していない限り、
常に`ColorSystemSupport.Detect``AnsiSupport.Detect`を使用してください。_
## 例の実行
Spectre.Consoleでできることを見るために、
[dotnet-example](https://github.com/patriksvensson/dotnet-example)グローバルツールをインストールします。
```
> dotnet tool restore
```
このリポジトリで提供している例が一覧表示されます
```
> dotnet example
╭────────────┬───────────────────────────────────────┬──────────────────────────────────────────────────────╮
│ Name │ Path │ Description │
├────────────┼───────────────────────────────────────┼──────────────────────────────────────────────────────┤
│ Borders │ examples/Borders/Borders.csproj │ Demonstrates the different kind of borders. │
│ Calendars │ examples/Calendars/Calendars.csproj │ Demonstrates how to render calendars. │
│ Colors │ examples/Colors/Colors.csproj │ Demonstrates how to use colors in the console. │
│ Columns │ examples/Columns/Columns.csproj │ Demonstrates how to render data into columns. │
│ Emojis │ examples/Emojis/Emojis.csproj │ Demonstrates how to render emojis. │
│ Exceptions │ examples/Exceptions/Exceptions.csproj │ Demonstrates how to render formatted exceptions. │
│ Grids │ examples/Grids/Grids.csproj │ Demonstrates how to render grids in a console. │
│ Info │ examples/Info/Info.csproj │ Displays the capabilities of the current console. │
│ Links │ examples/Links/Links.csproj │ Demonstrates how to render links in a console. │
│ Panels │ examples/Panels/Panels.csproj │ Demonstrates how to render items in panels. │
│ Rules │ examples/Rules/Rules.csproj │ Demonstrates how to render horizontal rules (lines). │
│ Tables │ examples/Tables/Tables.csproj │ Demonstrates how to render tables in a console. │
│ Trees │ examples/Trees/Trees.csproj │ Demonstrates how to render trees in a console. │
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
```
そして、例を実行します
```
> dotnet example tables
┌──────────┬──────────┬────────┐
│ Foo │ Bar │ Baz │
├──────────┼──────────┼────────┤
│ Hello │ World! │ │
│ Bonjour │ le │ monde! │
│ Hej │ Världen! │ │
└──────────┴──────────┴────────┘
```
## クイックスタート
pectre.Consoleの利用を開始する最初の方法は、Nugetパッケージをインストールすることです。
```shell
> dotnet add package Spectre.Console
```
その後、`Spectre.Console`名前空間を参照する必要があります。一度参照したら、提供されている全ての機能を使用できます。
```csharp
using Spectre.Console
public static class Program
{
public static void Main(string[] args)
{
AnsiConsole.Markup("[underline red]Hello[/] World!");
}
}
```
## マークアップ
`Markup`クラスは、コンソールにリッチなテキストを出力することができます。
### 文法
コンソールマークアップはbbcodeに影響を受けた文法を利用します。角括弧でスタイルを書いたらスタイルを参照、例えば、`[bold red]`
は、`[/]`で閉じるまでスタイルが適用されます。
```csharp
AnsiConsole.Render(new Markup("[bold yellow]Hello[/] [red]World![/]"));
```
`Markup` クラスは`IRenderable`を実装しており、table、grid、Panelを使用できることを意味します。
`IRenderable`のレンダリングに対応している多くのクラスは、リッチテキストの描画を上書きます。
```csharp
var table = new Table();
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
table.AddColumn(new TableColumn("[blue]Bar[/]"));
```
### 便利なメソッド
`AnsiConsole`には、新しい`Markup`インスタンスをインスタンス化することなく、コンソールにマークアップテキストを書き込める便利なメソッドがあります。
```csharp
AnsiConsole.Markup("[underline green]Hello[/] ");
AnsiConsole.MarkupLine("[bold]World[/]");
```
### エスケープ文字列
`[`を出力するために、 `[[`を利用し、`]`を出力するために`]]`を利用します。
```csharp
AnsiConsole.Markup("[[Hello]] "); // [Hello]
AnsiConsole.Markup("[red][[World]][/]"); // [World]
```
`SafeMarkup`拡張メソッドを使用することもできます。
```csharp
AnsiConsole.Markup("[red]{0}[/]", "Hello [World]".SafeMarkup());
```
### カラー
`new Style(foreground: Color.Maroon)`のようなコード、または、`AnsiConsole.Markup("[maroon on blue]Hello[/]")`のようなマークアップテキストで色を使用できます。
### 背景色の設定
カラー指定の際に、`on`を付けることで、マークアップで背景色を設定できます。
```
[bold yellow on blue]Hello[/]
[default on blue]World[/]
```
### 絵文字の描画
マークアップの一部として絵文字を出力するために、emojiショートコードが使用できます。
```csharp
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
```
emojiのスタイルについては、付録の[Emoji](./appendix/emojis) を参照してください。
### カラー
上の例では、全ての色は名前で参照されています。
しかし、16進数やRGB表現をマークダウンで色指定に使用できます。
```csharp
AnsiConsole.Markup("[red]Foo[/] ");
AnsiConsole.Markup("[#ff0000]Bar[/] ");
AnsiConsole.Markup("[rgb(255,0,0)]Baz[/] ");
```
## 絵文字
どのような絵文字が使用できるかは、使用しているOSやターミナルに依存し、どのように表示されるかは保証されません。絵文字の幅計算は正確ではないため、表、パネル、グリッドで使用する場合は表示がずれるかもしれません。
完全な互換性を確保するために、Unicode 13.0 より以前の`Emoji_Presentation`カテゴリにあるものだけを使用することを検討してください。
公式の絵文字一覧
https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
```csharp
// Markup
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
// Constant
var hello = "Hello " + Emoji.Known.GlobeShowingEuropeAfrica;
```
テキスト内の絵文字を置き換えることができます。
```csharp
var phrase = "Mmmm :birthday_cake:";
var rendered
```
既存の絵文字を別のものにしたり、完全に新しい物を追加したいことがあります。このために、`Emoji.Remap`メソッドを使用できます。
この方法は、マークアップ文字と`Emoji.Replace`の両方で動作します。
```csharp
// Remap the emoji
Emoji.Remap("globe_showing_europe_africa", "😄");
// Render markup
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
// Replace emojis in string
var phrase = "Hello :globe_showing_europe_africa:!";
var rendered = Emoji.Replace(phrase);
```
## テーブル
テーブルはターミナルで表データを表示するのに完璧な方法です。
`Spectre.Console` は、テーブルの描画にとても優れていて、全てのカラムは中に合わせて調整してくれます。
`IRenderable`を実装しているものは、列ヘッダやセル、別のテーブルとして使用できます。
### 使い方
テーブルを描画するために、`Table`インスタンスを作成し、必要な数の列を追加し、行を追加します。
テーブルをコンソールの`Render`メソッドに渡して終わりです。
```csharp
// テーブルの作成
var table = new Table();
// 列の追加
table.AddColumn("Foo");
table.AddColumn(new TableColumn("Bar").Centered());
// 行の追加
table.AddRow("Baz", "[green]Qux[/]");
table.AddRow(new Markup("[blue]Corgi[/]"), new Panel("Waldo"));
// コンソールにテーブルの描画
AnsiConsole.Render(table);
```
これは次のように出力を描画します。
![Table](docs/input/assets/images/table.png)
### 罫線
```csharp
// 罫線を設定します
table.SetBorder(Border.None);
table.SetBorder(Border.Ascii);
table.SetBorder(Border.Square);
table.SetBorder(Border.Rounded);
```
### 拡大 / 縮小
```csharp
// テーブル幅を最大に設定します
table.Expand();
// テーブル幅を最小に設定します
table.Collapse();
```
### ヘッダーを隠す
```csharp
// 全ての列のヘッダーを隠します
table.HideHeaders();
```
### テーブル幅の設定
```csharp
// テーブル幅50セルに設定します
table.SetWidth(50);
```
### 整列(アライメント)
```csharp
// 整列を明示的に設定する
column.SetAlignment(Justify.Right);
```
### パディング
```csharp
// 左と右のパディングを設定する
column.SetPadding(left: 3, right: 5);
// 個別にパディングを設定する
column.PadLeft(3);
column.PadRight(5);
```
### 列改行の無効化
```csharp
// 列改行の無効化
column.NoWrap();
```
### 列幅の設定
```csharp
// 列幅の設定(これはまだ柔軟な拡張メソッドがありません)
column.Width = 15;
```
## 例外
例外はターミナルで見たときに読みやすいとは限りません。
`WriteException`メソッドを使用することで、例外をもう少し読みやすくすることができます。
```csharp
AnsiConsole.WriteException(ex);
```
![exception](docs/input/assets/images/exception.png)
### 例外の省略表示
例外の特定部分を短くして、さらに読みやすくしたり、パスをクリック可能なハイパーリンクにすることもできます。
ハイパーリンクがクリックできるかはターミナル次第です。
```csharp
AnsiConsole.WriteException(ex,
ExceptionFormats.ShortenPaths | ExceptionFormats.ShortenTypes |
ExceptionFormats.ShortenMethods | ExceptionFormats.ShowLinks);
```
![exception](docs/input/assets/images/compact_exception.png)
### 例外出力のカスタマイズ
例外の特定部分を短縮するだけでなく、デフォルトのスタイルを上書きすることもできます。
```csharp
AnsiConsole.WriteException(ex, new ExceptionSettings
{
Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
Style = new ExceptionStyle
{
Exception = Style.WithForeground(Color.Grey),
Message = Style.WithForeground(Color.White),
NonEmphasized = Style.WithForeground(Color.Cornsilk1),
Parenthesis = Style.WithForeground(Color.Cornsilk1),
Method = Style.WithForeground(Color.Red),
ParameterName = Style.WithForeground(Color.Cornsilk1),
ParameterType = Style.WithForeground(Color.Red),
Path = Style.WithForeground(Color.Red),
LineNumber = Style.WithForeground(Color.Cornsilk1),
}
});
```
![exception](docs/input/assets/images/custom_exception.png)

390
README.md
View File

@@ -2,20 +2,18 @@
_[![Spectre.Console NuGet Version](https://img.shields.io/nuget/v/spectre.console.svg?style=flat&label=NuGet%3A%20Spectre.Console)](https://www.nuget.org/packages/spectre.console)_
A .NET Standard 2.0 library that makes it easier to create beautiful console applications.
A .NET 5/.NET Standard 2.0 library that makes it easier to create beautiful, cross platform, console applications.
It is heavily inspired by the excellent [Rich library](https://github.com/willmcgugan/rich)
for Python.
## Table of Contents
1. [Features](#features)
2. [Example](#example)
3. [Usage](#usage)
3.1. [Using the static API](#using-the-static-api)
3.2. [Creating a console](#creating-a-console)
4. [Running examples](#running-examples)
5. [Available styles](#available-styles)
6. [Predefined colors](#predefined-colors)
2. [Installing](#installing)
3. [Documentation](#documentation)
4. [Examples](#examples)
5. [Sponsors](#sponsors)
5. [License](#license)
## Features
@@ -26,377 +24,69 @@ for Python.
and blinking text.
* Supports 3/4/8/24-bit colors in the terminal.
The library will detect the capabilities of the current terminal
and downgrade colors as needed.
and downgrade colors as needed.
## Example
![Example](resources/gfx/screenshots/example.png)
![Example](docs/input/assets/images/example.png)
## Usage
## Installing
The `Spectre.Console` API is stateful and is not thread-safe.
If you need to write to the console from different threads, make sure that
you take appropriate precautions, just like when you use the
regular `System.Console` API.
If the current terminal does not support ANSI escape sequences,
`Spectre.Console` will fallback to using the `System.Console` API.
_NOTE: This library is currently under development and API's
might change or get removed at any point up until a 1.0 release._
### Using the static API
The static API is perfect when you just want to output text
like you usually do with the `System.Console` API, but prettier.
The fastest way of getting started using `Spectre.Console` is to install the NuGet package.
```csharp
AnsiConsole.Foreground = Color.CornflowerBlue;
AnsiConsole.Decoration = Decoration.Underline | Decoration.Bold;
AnsiConsole.WriteLine("Hello World!");
AnsiConsole.Reset();
AnsiConsole.MarkupLine("[bold yellow on red]{0}[/] [underline]world[/]!", "Goodbye");
dotnet add package Spectre.Console
```
If you want to get a reference to the default `IAnsiConsole`,
you can access it via `AnsiConsole.Console`.
## Documentation
### Creating a console
The documentation for `Spectre.Console` can be found at
https://spectreconsole.net/
Sometimes it's useful to explicitly create a console with specific
capabilities, such as during unit testing when you want control
over the environment your code runs in.
## Examples
It's recommended to not use `AnsiConsole` in code that run as
part of a unit test.
```csharp
IAnsiConsole console = AnsiConsole.Create(
new AnsiConsoleSettings()
{
Ansi = AnsiSupport.Yes,
ColorSystem = ColorSystemSupport.TrueColor,
Out = new StringWriter(),
});
```
_NOTE: Even if you can specify a specific color system to use
when manually creating a console, remember that the user's terminal
might not be able to use it, so unless you're creating an IAnsiConsole
for testing, always use `ColorSystemSupport.Detect` and `AnsiSupport.Detect`._
## Running examples
To see Spectre.Console in action, install the
To see `Spectre.Console` in action, install the
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
global tool.
```
> dotnet tool install -g dotnet-example
> dotnet tool restore
```
Now you can list available examples in this repository:
```
> dotnet example
╭────────┬───────────────────────────────┬─────────────────────────────────────────────────╮
│ Name │ Path │ Description │
├────────┼───────────────────────────────┼─────────────────────────────────────────────────┤
│ Colors │ examples/Colors/Colors.csproj │ Demonstrates how to use colors in the console. │
│ Grid │ examples/Grid/Grid.csproj │ Demonstrates how to render grids in a console. │
│ Panel │ examples/Panel/Panel.csproj │ Demonstrates how to render items in panels. │
│ Table │ examples/Table/Table.csproj │ Demonstrates how to render tables in a console. │
╰────────┴───────────────────────────────┴─────────────────────────────────────────────────╯
```
And to run an example:
```
> dotnet example table
┌──────────┬──────────┬────────┐
│ Foo │ Bar │ Baz │
├──────────┼──────────┼────────┤
│ Hello │ World! │ │
│ Bonjour │ le │ monde! │
│ Hej │ Världen! │ │
└──────────┴──────────┴────────┘
> dotnet example tables
```
## Available styles
## Sponsors
_NOTE: Not all styles are supported in every terminal._
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
Spectre.Console to show their support and to ensure the longevity of the project.
Name | Description
--- | ---
`bold` | Bold text
`dim` | Dim or faint text
`italic` | Italic text
`underline` | Underlined text
`invert` | Swaps the foreground and background colors
`conceal` | Hides the text
`slowblink` | Makes text blink slowly
`rapidblink` | Makes text blink
`strikethrough` | Shows text with a horizontal line through the center
* [Rodney Littles II](https://github.com/RLittlesII)
* [Martin Björkström](https://github.com/bjorkstromm)
* [Dave Glick](https://github.com/daveaglick)
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
* [Andrew McClenaghan](https://github.com/andymac4182)
* [C. Augusto Proiete](https://github.com/augustoproiete)
* [Viktor Elofsson](https://github.com/vktr)
* [Steven Knox](https://github.com/stevenknox)
* [David Pendray](https://github.com/dpen2000)
* [Elmah.io](https://github.com/elmahio)
## Predefined colors
I really appreciate it.
**Thank you very much!**
Number | Name | RGB | Hex | System.ConsoleColor
--- | --- | --- | --- | ---
`0` | `black` | `0,0,0` | `#000000` | `Black`
`1` | `maroon` | `128,0,0` | `#800000` | `DarkRed`
`2` | `green` | `0,128,0` | `#008000` | `DarkGreen`
`3` | `olive` | `128,128,0` | `#808000` | `DarkYellow`
`4` | `navy` | `0,0,128` | `#000080` | `DarkBlue`
`5` | `purple` | `128,0,128` | `#800080` | `DarkMagenta`
`6` | `teal` | `0,128,128` | `#008080` | `DarkCyan`
`7` | `silver` | `192,192,192` | `#c0c0c0` | `Gray`
`8` | `grey` | `128,128,128` | `#808080` | `DarkGray`
`9` | `red` | `255,0,0` | `#ff0000` | `Red`
`10` | `lime` | `0,255,0` | `#00ff00` | `Green`
`11` | `yellow` | `255,255,0` | `#ffff00` | `Yellow`
`12` | `blue` | `0,0,255` | `#0000ff` | `Blue`
`13` | `fuchsia` | `255,0,255` | `#ff00ff` | `Magenta`
`14` | `aqua` | `0,255,255` | `#00ffff` | `Cyan`
`15` | `white` | `255,255,255` | `#ffffff` | `White`
`16` | `grey0` | `0,0,0` | `#000000`
`17` | `navyblue` | `0,0,95` | `#00005f`
`18` | `darkblue` | `0,0,135` | `#000087`
`19` | `blue3` | `0,0,175` | `#0000af`
`20` | `blue3_1` | `0,0,215` | `#0000d7`
`21` | `blue1` | `0,0,255` | `#0000ff`
`22` | `darkgreen` | `0,95,0` | `#005f00`
`23` | `deepskyblue4` | `0,95,95` | `#005f5f`
`24` | `deepskyblue4_1` | `0,95,135` | `#005f87`
`25` | `deepskyblue4_2` | `0,95,175` | `#005faf`
`26` | `dodgerblue3` | `0,95,215` | `#005fd7`
`27` | `dodgerblue2` | `0,95,255` | `#005fff`
`28` | `green4` | `0,135,0` | `#008700`
`29` | `springgreen4` | `0,135,95` | `#00875f`
`30` | `turquoise4` | `0,135,135` | `#008787`
`31` | `deepskyblue3` | `0,135,175` | `#0087af`
`32` | `deepskyblue3_1` | `0,135,215` | `#0087d7`
`33` | `dodgerblue1` | `0,135,255` | `#0087ff`
`34` | `green3` | `0,175,0` | `#00af00`
`35` | `springgreen3` | `0,175,95` | `#00af5f`
`36` | `darkcyan` | `0,175,135` | `#00af87`
`37` | `lightseagreen` | `0,175,175` | `#00afaf`
`38` | `deepskyblue2` | `0,175,215` | `#00afd7`
`39` | `deepskyblue1` | `0,175,255` | `#00afff`
`40` | `green3_1` | `0,215,0` | `#00d700`
`41` | `springgreen3_1` | `0,215,95` | `#00d75f`
`42` | `springgreen2` | `0,215,135` | `#00d787`
`43` | `cyan3` | `0,215,175` | `#00d7af`
`44` | `darkturquoise` | `0,215,215` | `#00d7d7`
`45` | `turquoise2` | `0,215,255` | `#00d7ff`
`46` | `green1` | `0,255,0` | `#00ff00`
`47` | `springgreen2_1` | `0,255,95` | `#00ff5f`
`48` | `springgreen1` | `0,255,135` | `#00ff87`
`49` | `mediumspringgreen` | `0,255,175` | `#00ffaf`
`50` | `cyan2` | `0,255,215` | `#00ffd7`
`51` | `cyan1` | `0,255,255` | `#00ffff`
`52` | `darkred` | `95,0,0` | `#5f0000`
`53` | `deeppink4` | `95,0,95` | `#5f005f`
`54` | `purple4` | `95,0,135` | `#5f0087`
`55` | `purple4_1` | `95,0,175` | `#5f00af`
`56` | `purple3` | `95,0,215` | `#5f00d7`
`57` | `blueviolet` | `95,0,255` | `#5f00ff`
`58` | `orange4` | `95,95,0` | `#5f5f00`
`59` | `grey37` | `95,95,95` | `#5f5f5f`
`60` | `mediumpurple4` | `95,95,135` | `#5f5f87`
`61` | `slateblue3` | `95,95,175` | `#5f5faf`
`62` | `slateblue3_1` | `95,95,215` | `#5f5fd7`
`63` | `royalblue1` | `95,95,255` | `#5f5fff`
`64` | `chartreuse4` | `95,135,0` | `#5f8700`
`65` | `darkseagreen4` | `95,135,95` | `#5f875f`
`66` | `paleturquoise4` | `95,135,135` | `#5f8787`
`67` | `steelblue` | `95,135,175` | `#5f87af`
`68` | `steelblue3` | `95,135,215` | `#5f87d7`
`69` | `cornflowerblue` | `95,135,255` | `#5f87ff`
`70` | `chartreuse3` | `95,175,0` | `#5faf00`
`71` | `darkseagreen4_1` | `95,175,95` | `#5faf5f`
`72` | `cadetblue` | `95,175,135` | `#5faf87`
`73` | `cadetblue_1` | `95,175,175` | `#5fafaf`
`74` | `skyblue3` | `95,175,215` | `#5fafd7`
`75` | `steelblue1` | `95,175,255` | `#5fafff`
`76` | `chartreuse3_1` | `95,215,0` | `#5fd700`
`77` | `palegreen3` | `95,215,95` | `#5fd75f`
`78` | `seagreen3` | `95,215,135` | `#5fd787`
`79` | `aquamarine3` | `95,215,175` | `#5fd7af`
`80` | `mediumturquoise` | `95,215,215` | `#5fd7d7`
`81` | `steelblue1_1` | `95,215,255` | `#5fd7ff`
`82` | `chartreuse2` | `95,255,0` | `#5fff00`
`83` | `seagreen2` | `95,255,95` | `#5fff5f`
`84` | `seagreen1` | `95,255,135` | `#5fff87`
`85` | `seagreen1_1` | `95,255,175` | `#5fffaf`
`86` | `aquamarine1` | `95,255,215` | `#5fffd7`
`87` | `darkslategray2` | `95,255,255` | `#5fffff`
`88` | `darkred_1` | `135,0,0` | `#870000`
`89` | `deeppink4_1` | `135,0,95` | `#87005f`
`90` | `darkmagenta` | `135,0,135` | `#870087`
`91` | `darkmagenta_1` | `135,0,175` | `#8700af`
`92` | `darkviolet` | `135,0,215` | `#8700d7`
`93` | `purple_1` | `135,0,255` | `#8700ff`
`94` | `orange4_1` | `135,95,0` | `#875f00`
`95` | `lightpink4` | `135,95,95` | `#875f5f`
`96` | `plum4` | `135,95,135` | `#875f87`
`97` | `mediumpurple3` | `135,95,175` | `#875faf`
`98` | `mediumpurple3_1` | `135,95,215` | `#875fd7`
`99` | `slateblue1` | `135,95,255` | `#875fff`
`100` | `yellow4` | `135,135,0` | `#878700`
`101` | `wheat4` | `135,135,95` | `#87875f`
`102` | `grey53` | `135,135,135` | `#878787`
`103` | `lightslategrey` | `135,135,175` | `#8787af`
`104` | `mediumpurple` | `135,135,215` | `#8787d7`
`105` | `lightslateblue` | `135,135,255` | `#8787ff`
`106` | `yellow4_1` | `135,175,0` | `#87af00`
`107` | `darkolivegreen3` | `135,175,95` | `#87af5f`
`108` | `darkseagreen` | `135,175,135` | `#87af87`
`109` | `lightskyblue3` | `135,175,175` | `#87afaf`
`110` | `lightskyblue3_1` | `135,175,215` | `#87afd7`
`111` | `skyblue2` | `135,175,255` | `#87afff`
`112` | `chartreuse2_1` | `135,215,0` | `#87d700`
`113` | `darkolivegreen3_1` | `135,215,95` | `#87d75f`
`114` | `palegreen3_1` | `135,215,135` | `#87d787`
`115` | `darkseagreen3` | `135,215,175` | `#87d7af`
`116` | `darkslategray3` | `135,215,215` | `#87d7d7`
`117` | `skyblue1` | `135,215,255` | `#87d7ff`
`118` | `chartreuse1` | `135,255,0` | `#87ff00`
`119` | `lightgreen` | `135,255,95` | `#87ff5f`
`120` | `lightgreen_1` | `135,255,135` | `#87ff87`
`121` | `palegreen1` | `135,255,175` | `#87ffaf`
`122` | `aquamarine1_1` | `135,255,215` | `#87ffd7`
`123` | `darkslategray1` | `135,255,255` | `#87ffff`
`124` | `red3` | `175,0,0` | `#af0000`
`125` | `deeppink4_2` | `175,0,95` | `#af005f`
`126` | `mediumvioletred` | `175,0,135` | `#af0087`
`127` | `magenta3` | `175,0,175` | `#af00af`
`128` | `darkviolet_1` | `175,0,215` | `#af00d7`
`129` | `purple_2` | `175,0,255` | `#af00ff`
`130` | `darkorange3` | `175,95,0` | `#af5f00`
`131` | `indianred` | `175,95,95` | `#af5f5f`
`132` | `hotpink3` | `175,95,135` | `#af5f87`
`133` | `mediumorchid3` | `175,95,175` | `#af5faf`
`134` | `mediumorchid` | `175,95,215` | `#af5fd7`
`135` | `mediumpurple2` | `175,95,255` | `#af5fff`
`136` | `darkgoldenrod` | `175,135,0` | `#af8700`
`137` | `lightsalmon3` | `175,135,95` | `#af875f`
`138` | `rosybrown` | `175,135,135` | `#af8787`
`139` | `grey63` | `175,135,175` | `#af87af`
`140` | `mediumpurple2_1` | `175,135,215` | `#af87d7`
`141` | `mediumpurple1` | `175,135,255` | `#af87ff`
`142` | `gold3` | `175,175,0` | `#afaf00`
`143` | `darkkhaki` | `175,175,95` | `#afaf5f`
`144` | `navajowhite3` | `175,175,135` | `#afaf87`
`145` | `grey69` | `175,175,175` | `#afafaf`
`146` | `lightsteelblue3` | `175,175,215` | `#afafd7`
`147` | `lightsteelblue` | `175,175,255` | `#afafff`
`148` | `yellow3` | `175,215,0` | `#afd700`
`149` | `darkolivegreen3_2` | `175,215,95` | `#afd75f`
`150` | `darkseagreen3_1` | `175,215,135` | `#afd787`
`151` | `darkseagreen2` | `175,215,175` | `#afd7af`
`152` | `lightcyan3` | `175,215,215` | `#afd7d7`
`153` | `lightskyblue1` | `175,215,255` | `#afd7ff`
`154` | `greenyellow` | `175,255,0` | `#afff00`
`155` | `darkolivegreen2` | `175,255,95` | `#afff5f`
`156` | `palegreen1_1` | `175,255,135` | `#afff87`
`157` | `darkseagreen2_1` | `175,255,175` | `#afffaf`
`158` | `darkseagreen1` | `175,255,215` | `#afffd7`
`159` | `paleturquoise1` | `175,255,255` | `#afffff`
`160` | `red3_1` | `215,0,0` | `#d70000`
`161` | `deeppink3` | `215,0,95` | `#d7005f`
`162` | `deeppink3_1` | `215,0,135` | `#d70087`
`163` | `magenta3_1` | `215,0,175` | `#d700af`
`164` | `magenta3_2` | `215,0,215` | `#d700d7`
`165` | `magenta2` | `215,0,255` | `#d700ff`
`166` | `darkorange3_1` | `215,95,0` | `#d75f00`
`167` | `indianred_1` | `215,95,95` | `#d75f5f`
`168` | `hotpink3_1` | `215,95,135` | `#d75f87`
`169` | `hotpink2` | `215,95,175` | `#d75faf`
`170` | `orchid` | `215,95,215` | `#d75fd7`
`171` | `mediumorchid1` | `215,95,255` | `#d75fff`
`172` | `orange3` | `215,135,0` | `#d78700`
`173` | `lightsalmon3_1` | `215,135,95` | `#d7875f`
`174` | `lightpink3` | `215,135,135` | `#d78787`
`175` | `pink3` | `215,135,175` | `#d787af`
`176` | `plum3` | `215,135,215` | `#d787d7`
`177` | `violet` | `215,135,255` | `#d787ff`
`178` | `gold3_1` | `215,175,0` | `#d7af00`
`179` | `lightgoldenrod3` | `215,175,95` | `#d7af5f`
`180` | `tan` | `215,175,135` | `#d7af87`
`181` | `mistyrose3` | `215,175,175` | `#d7afaf`
`182` | `thistle3` | `215,175,215` | `#d7afd7`
`183` | `plum2` | `215,175,255` | `#d7afff`
`184` | `yellow3_1` | `215,215,0` | `#d7d700`
`185` | `khaki3` | `215,215,95` | `#d7d75f`
`186` | `lightgoldenrod2` | `215,215,135` | `#d7d787`
`187` | `lightyellow3` | `215,215,175` | `#d7d7af`
`188` | `grey84` | `215,215,215` | `#d7d7d7`
`189` | `lightsteelblue1` | `215,215,255` | `#d7d7ff`
`190` | `yellow2` | `215,255,0` | `#d7ff00`
`191` | `darkolivegreen1` | `215,255,95` | `#d7ff5f`
`192` | `darkolivegreen1_1` | `215,255,135` | `#d7ff87`
`193` | `darkseagreen1_1` | `215,255,175` | `#d7ffaf`
`194` | `honeydew2` | `215,255,215` | `#d7ffd7`
`195` | `lightcyan1` | `215,255,255` | `#d7ffff`
`196` | `red1` | `255,0,0` | `#ff0000`
`197` | `deeppink2` | `255,0,95` | `#ff005f`
`198` | `deeppink1` | `255,0,135` | `#ff0087`
`199` | `deeppink1_1` | `255,0,175` | `#ff00af`
`200` | `magenta2_1` | `255,0,215` | `#ff00d7`
`201` | `magenta1` | `255,0,255` | `#ff00ff`
`202` | `orangered1` | `255,95,0` | `#ff5f00`
`203` | `indianred1` | `255,95,95` | `#ff5f5f`
`204` | `indianred1_1` | `255,95,135` | `#ff5f87`
`205` | `hotpink` | `255,95,175` | `#ff5faf`
`206` | `hotpink_1` | `255,95,215` | `#ff5fd7`
`207` | `mediumorchid1_1` | `255,95,255` | `#ff5fff`
`208` | `darkorange` | `255,135,0` | `#ff8700`
`209` | `salmon1` | `255,135,95` | `#ff875f`
`210` | `lightcoral` | `255,135,135` | `#ff8787`
`211` | `palevioletred1` | `255,135,175` | `#ff87af`
`212` | `orchid2` | `255,135,215` | `#ff87d7`
`213` | `orchid1` | `255,135,255` | `#ff87ff`
`214` | `orange1` | `255,175,0` | `#ffaf00`
`215` | `sandybrown` | `255,175,95` | `#ffaf5f`
`216` | `lightsalmon1` | `255,175,135` | `#ffaf87`
`217` | `lightpink1` | `255,175,175` | `#ffafaf`
`218` | `pink1` | `255,175,215` | `#ffafd7`
`219` | `plum1` | `255,175,255` | `#ffafff`
`220` | `gold1` | `255,215,0` | `#ffd700`
`221` | `lightgoldenrod2_1` | `255,215,95` | `#ffd75f`
`222` | `lightgoldenrod2_2` | `255,215,135` | `#ffd787`
`223` | `navajowhite1` | `255,215,175` | `#ffd7af`
`224` | `mistyrose1` | `255,215,215` | `#ffd7d7`
`225` | `thistle1` | `255,215,255` | `#ffd7ff`
`226` | `yellow1` | `255,255,0` | `#ffff00`
`227` | `lightgoldenrod1` | `255,255,95` | `#ffff5f`
`228` | `khaki1` | `255,255,135` | `#ffff87`
`229` | `wheat1` | `255,255,175` | `#ffffaf`
`230` | `cornsilk1` | `255,255,215` | `#ffffd7`
`231` | `grey100` | `255,255,255` | `#ffffff`
`232` | `grey3` | `8,8,8` | `#080808`
`233` | `grey7` | `18,18,18` | `#121212`
`234` | `grey11` | `28,28,28` | `#1c1c1c`
`235` | `grey15` | `38,38,38` | `#262626`
`236` | `grey19` | `48,48,48` | `#303030`
`237` | `grey23` | `58,58,58` | `#3a3a3a`
`238` | `grey27` | `68,68,68` | `#444444`
`239` | `grey30` | `78,78,78` | `#4e4e4e`
`240` | `grey35` | `88,88,88` | `#585858`
`241` | `grey39` | `98,98,98` | `#626262`
`242` | `grey42` | `108,108,108` | `#6c6c6c`
`243` | `grey46` | `118,118,118` | `#767676`
`244` | `grey50` | `128,128,128` | `#808080`
`245` | `grey54` | `138,138,138` | `#8a8a8a`
`246` | `grey58` | `148,148,148` | `#949494`
`247` | `grey62` | `158,158,158` | `#9e9e9e`
`248` | `grey66` | `168,168,168` | `#a8a8a8`
`249` | `grey70` | `178,178,178` | `#b2b2b2`
`250` | `grey74` | `188,188,188` | `#bcbcbc`
`251` | `grey78` | `198,198,198` | `#c6c6c6`
`252` | `grey82` | `208,208,208` | `#d0d0d0`
`253` | `grey85` | `218,218,218` | `#dadada`
`254` | `grey89` | `228,228,228` | `#e4e4e4`
`255` | `grey93` | `238,238,238` | `#eeeeee`
## License
Copyright © Patrik Svensson, Phil Scott
Spectre.Console is provided as-is under the MIT license. For more information see LICENSE.
* For SixLabors.ImageSharp, see https://github.com/SixLabors/ImageSharp/blob/master/LICENSE

65
README.zh.md Normal file
View File

@@ -0,0 +1,65 @@
# `Spectre.Console`
_[![Spectre.Console NuGet Version](https://img.shields.io/nuget/v/spectre.console.svg?style=flat&label=NuGet%3A%20Spectre.Console)](https://www.nuget.org/packages/spectre.console)_
`Spectre.Console`是一个 .NET 5/.NET Standard 2.0 的库,能让您在终端里更方便地生成精美的界面。
深受 [Rich](https://github.com/willmcgugan/rich) 这个优秀库的启发。
## 目录
1. [功能](#features)
2. [安装](#installing)
3. [文档](#documentation)
4. [例子](#examples)
5. [License](#license)
## 功能
* 编写时考虑到了单元测试。
* 支持 tables、grid、panel 和 [rich](https://github.com/willmcgugan/rich) 所支持的标记语言。
* 支持大部分的 SRG 参数,包括粗体、暗淡字、斜体、下划线、删除线和闪烁文本。
* 支持终端显示 3/4/8/24 位色。自动检测终端类型,自适应颜色范围。
![例子](resources/gfx/screenshots/example.png)
## 安装
最快的安装方式就是用NuGet包管理直接安装Spectre.Console。
```csharp
dotnet add package Spectre.Console
```
## 文档
`Spectre.Console`的文档可以在这里查看
https://spectreconsole.net/
## 例子
如果想直接运行`Spectre.Console`的例子,则需要安装[dotnet-example](https://github.com/patriksvensson/dotnet-example)工具。
```
> dotnet tool restore
```
然后你可以列出仓库里的所有例子:
```
> dotnet example
```
跑一个看看效果:
```
> dotnet example tables
```
## License
版权所有 © Patrik Svensson, Phil Scott
Spectre.Console 基于 MIT 协议提供。查看 LICENSE 文件了解更多信息。
* SixLabors.ImageSharp 的协议请查看 https://github.com/SixLabors/ImageSharp/blob/master/LICENSE

View File

@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
</PropertyGroup>
<ItemGroup>
@@ -22,8 +23,27 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Statiq.Web" Version="1.0.0-alpha.9" />
<PackageReference Include="NJsonSchema" Version="10.1.12" />
<None Remove="src\Data\emojis.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="src\Data\emojis.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.13" />
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="input\assets\images\emojis\" />
</ItemGroup>
<Target Name="Versioning" BeforeTargets="MinVer">
<PropertyGroup Label="Build">
<MinVerDefaultPreReleasePhase>preview</MinVerDefaultPreReleasePhase>
<MinVerVerbosity>normal</MinVerVerbosity>
</PropertyGroup>
</Target>
</Project>

1
docs/Preview.ps1 Normal file
View File

@@ -0,0 +1 @@
dotnet run -- preview

View File

@@ -11,14 +11,14 @@ namespace Docs
public static async Task<int> Main(string[] args) =>
await Bootstrapper.Factory
.CreateWeb(args)
.AddSetting(Keys.Host, "spectresystems.github.io")
.AddSetting(Keys.LinkRoot, "/spectre.console")
.AddSetting(Keys.Host, "spectreconsole.net")
.AddSetting(Keys.LinksUseHttps, true)
.AddSetting(Constants.EditLink, ConfigureEditLink())
.ConfigureSite("spectresystems", "spectre.console", "main")
.ConfigureSite("spectreconsole", "spectre.console", "main")
.ConfigureDeployment(deployBranch: "docs")
.AddShortcode("Children", typeof(ChildrenShortcode))
.AddShortcode("ColorTable", typeof(ColorTableShortcode))
.AddShortcode("EmojiTable", typeof(EmojiTableShortcode))
.AddPipelines()
.RunAsync();

44
docs/README.md Normal file
View File

@@ -0,0 +1,44 @@
# Documentation
To start contributing to the [Spectre.Console](https://github.com/spectreconsole/spectre.console) documentation, you will need the [.NET Core SDK](https://dot.net) 3.1 or higher.
## Running Preview Site
The documentation site uses [Statiq](https://statiq.dev), a static site generator. To build the documentation site run the following in a command-line terminal.
```
> Preview.ps1
```
After the build is complete, you can navigate to [http://localhost:5080/spectre.console](http://localhost:5080/spectre.console).
**Note that the site runs under a virtual directory.**
## Editing Content
The documentation is written using [Markdown](https://www.markdownguide.org/basic-syntax/).
Markdown files can be found under the following directories:
- [/input](./input)
- [/appendix](./input/appendix)
## Editing Layout
Layout and styling can also be found in the [input](./input) directory. Look for Sass, Css, and Images under the [assets](./input/assets) directory.
## Custom Build Features
The documentation site has custom enhancements to Statiq located under the [./src](./src) directory.
## License
MIT License
Copyright (c) 2020 Patrik Svensson, Phil Scott
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

1
docs/input/CNAME Normal file
View File

@@ -0,0 +1 @@
spectreconsole.net

View File

@@ -1,12 +1,12 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/spectre.console/assets/bootstrap/bootstrap.css" rel="stylesheet" />
<link href="/spectre.console/assets/css/styles.css" rel="stylesheet" />
<link href="@Context.GetLink("/assets/bootstrap/bootstrap.css")" rel="stylesheet" />
<link href="@Context.GetLink("/assets/css/styles.css")" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&family=Roboto+Slab:wght@400;700&family=Roboto:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap" rel="stylesheet" data-no-mirror>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.19.0/themes/prism.css">
@@ -26,13 +26,34 @@
</head>
<body class="d-flex flex-column">
<div class="flex-grow-1 d-flex flex-column">
<nav id="topnav" class="navbar navbar-expand-lg navbar-light">
<div class="container py-3">
<a class="navbar-brand" href="@Context.GetLink("/")"><img id="logo" src="@Context.GetLink("/assets/logo.svg")" alt="Spectre.Console"> Spectre.Console</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav mr-auto">
</ul>
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link font-weight-light font-size-lg text-red" href="https://github.com/sponsors/patriksvensson"><i class="far fa-heart"></i> Sponsor</a>
</li>
<li class="nav-item">
<a class="nav-link font-weight-light font-size-lg" href="https://github.com/spectreconsole/spectre.console"><i class="fab fa-github"></i> GitHub</a>
</li>
</ul>
</div>
</div>
</nav>
@if (IsSectionDefined(Constants.Sections.Splash))
{
@RenderSection(Constants.Sections.Splash, false)
}
@{
string section = Document.Destination.Segments.Length > 1 ? Document.Destination.Segments[0].ToString() : null;
@{
string section = "docs";
}
<div class="flex-grow-1 d-flex bg-body flex-column @(section != null ? "section-" + section : null)">
@@ -41,7 +62,7 @@
<div id="titlebar" class="py-4">
<div class="container">
<div class="row">
@{
@{
string titleBarClasses = Document.GetBool(Constants.NoSidebar) ? string.Empty : "offset-md-3 offset-lg-2";
}
<div class="@titleBarClasses px-3 px-md-0">
@@ -76,7 +97,7 @@
</div>
</div>
}
<div class="flex-grow-1 d-flex flex-column bg-body">
@if (Document.GetBool(Constants.NoContainer))
{
@@ -105,21 +126,41 @@
}
else
{
IDocument root = Outputs[nameof(Content)].First(x => x.Destination == section + "/index.html");
IDocument root = OutputPages["index.html"].First();
<div class="sidebar-nav-item @(Document.IdEquals(root) ? "active" : null)">
@Html.DocumentLink(root)
@if(root.ShowLink())
{
@Html.DocumentLink(root)
}
else
{
@root.GetTitle()
}
</div>
@foreach (IDocument document in root.GetChildren().OnlyVisible())
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
{
<div class="sidebar-nav-item @(Document.IdEquals(document) ? "active" : null) @(document.HasChildren() ? "has-children" : null)">
@Html.DocumentLink(document)
if(string.IsNullOrWhiteSpace(document.GetTitle()))
{
continue;
}
DocumentList<IDocument> documentChildren = OutputPages.GetChildrenOf(document);
<div class="sidebar-nav-item @(Document.IdEquals(document) ? "active" : null) @(documentChildren.Any() ? "has-children" : null)">
@if(document.ShowLink())
{
@Html.DocumentLink(document)
}
else
{
@document.GetTitle()
}
</div>
@if (document.HasVisibleChildren())
@if (documentChildren.OnlyVisible().Any())
{
<div class="sidebar-nav-children @(Document.IdEquals(document) || document.GetChildren().Any(x => Document.IdEquals(x)) ? "active" : null)">
@foreach (IDocument child in document.GetChildren().OnlyVisible())
<div class="sidebar-nav-children @(Document.IdEquals(document) || documentChildren.Any(x => Document.IdEquals(x)) ? "active" : null)">
@foreach (IDocument child in documentChildren.OnlyVisible())
{
<div class="sidebar-nav-child @(Document.IdEquals(child) ? "active" : null)">
@Html.DocumentLink(child)
@@ -161,7 +202,10 @@
</div>
<div id="footer" class="p-3 text-white font-size-sm">
<div class="container">
<div>© @DateTime.Today.Year Spectre Systems AB</div>
<div>
<span>© @DateTime.Today.Year Patrik Svensson, Phil Scott</span>
<span class="float-right" style="color: #888888;">@VersionUtilities.GetVersion()</span>
</div>
</div>
</div>
<script>
@@ -174,7 +218,7 @@
},
startOnLoad: false,
cloneCssStyles: false
});
});
mermaid.init(undefined, ".mermaid");
// Remove the max-width setting that Mermaid sets
@@ -193,13 +237,13 @@
center: true,
maxZoom: 20,
zoomScaleSensitivity: 0.6
});
});
// Do the reset once right away to fit the diagram
panZoom.resize();
panZoom.fit();
panZoom.center();
$(window).resize(function(){
panZoom.resize();
panZoom.fit();

View File

@@ -3,5 +3,6 @@
@using Statiq.Web
@using Statiq.Web.Pipelines
@using Docs
@using Docs.Utilities;
@inherits StatiqRazorPage<IDocument>

View File

@@ -0,0 +1,33 @@
Title: Borders
Order: 2
---
There is different built-in borders you can use for tables and panels.
# Table borders
<img src="../assets/images/borders/table.png" style="max-width: 100%;">
## Example
To set a table border to `SimpleHeavy`:
```csharp
var table = new Table();
table.Border = TableBorder.SimpleHeavy;
```
---
# Panel borders
<img src="../assets/images/borders/panel.png" style="max-width: 100%;">
## Example
To set a panel border to `Rounded`:
```csharp
var panel = new Panel("Hello World");
panel.Border = BoxBorder.Rounded;
```

View File

@@ -0,0 +1,31 @@
Title: Colors
Order: 0
---
The following is a list of the standard 8-bit colors supported in terminals.
Note that the first 16 colors are generally defined by the system or your terminal software, and may not display exactly as rendered here.
# Usage
You can either use the colors in code, such as `new Style(foreground: Color.Maroon)` or
in markup text such as `AnsiConsole.Markup("[maroon on blue]Hello[/]")`.
# Standard colors
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">
<i class="fas fa-search" aria-hidden="true"></i>
</span>
</div>
<input
class="form-control w-100 filter"
data-table="color-results"
type="text" placeholder="Search Colors..." autocomplete="off"
aria-label="Search Colors">
</div>
<?# ColorTable /?>
<script type="text/javascript" src="../assets/js/table-search.js"></script>

View File

@@ -0,0 +1,72 @@
Title: Emojis
Order: 3
---
Please note that what emojis that can be used is completely up to
the operating system and/or terminal you're using, and no guarantees
can be made of how it will look. Calculating the width of emojis
is also not an exact science in many ways, so milage might vary when
used in tables, panels or grids.
To ensure best compatibility, consider only using emojis introduced
before Unicode 13.0 that belongs in the `Emoji_Presentation` category
in the official emoji list at
https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
# Usage
```csharp
// Markup
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
// Constant
var hello = "Hello " + Emoji.Known.GlobeShowingEuropeAfrica;
```
# Replacing emojis in text
```csharp
var phrase = "Mmmm :birthday_cake:";
var rendered = Emoji.Replace(phrase);
```
# Remapping or adding an emoji
Sometimes you want to remap an existing emoji, or
add a completely new one. For this you can use the
`Emoji.Remap` method. This approach works both with
markup strings and `Emoji.Replace`.
```csharp
// Remap the emoji
Emoji.Remap("globe_showing_europe_africa", "😄");
// Render markup
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
// Replace emojis in string
var phrase = "Hello :globe_showing_europe_africa:!";
var rendered = Emoji.Replace(phrase);
```
# Emojis
_The images in the table below might not render correctly in your
browser for the same reasons mentioned in the `Compatibility` section._
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">
<i class="fas fa-search" aria-hidden="true"></i>
</span>
</div>
<input
class="form-control w-100 filter"
data-table="emoji-results"
type="text" placeholder="Search Emojis..." autocomplete="off"
aria-label="Search Emojis">
</div>
<?# EmojiTable /?>
<script type="text/javascript" src="../assets/js/table-search.js"></script>

View File

@@ -0,0 +1,12 @@
Title: Appendix
Order: 100
---
<h1>Sections</h1>
<ul>
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
{
<li>@Html.DocumentLink(child)</li>
}
</ul>

View File

@@ -0,0 +1,43 @@
Title: Spinners
Order: 4
---
For all available spinners, see https://jsfiddle.net/sindresorhus/2eLtsbey/embedded/result/
# Usage
Spinners can be used with [Progress](xref:progress) and [Status](xref:status).
```csharp
AnsiConsole.Status()
.Spinner(Spinner.Known.Star)
.Start("Thinking...", ctx => {
// Omitted
});
```
# Implementing a spinner
To implement your own spinner, all you have to do is
inherit from the `Spinner` base class.
In the example below, the spinner will alterate between
the characters `A`, `B` and `C` every 100 ms.
```csharp
public sealed class MySpinner : Spinner
{
// The interval for each frame
public override TimeSpan Interval => TimeSpan.FromMilliseconds(100);
// Whether or not the spinner contains unicode characters
public override bool IsUnicode => false;
// The individual frames of the spinner
public override IReadOnlyList<string> Frames =>
new List<string>
{
"A", "B", "C",
};
}
```

View File

@@ -0,0 +1,44 @@
Title: Styles
Order: 1
---
Note that what styles that can be used is defined by the system or your terminal software, and may not appear as they should.
<table class="table">
<tr>
<td><code>bold</code></td>
<td>Bold text</td>
</tr>
<tr>
<td><code>dim</code></td>
<td>Dim or faint text</td>
</tr>
<tr>
<td><code>italic</code></td>
<td>Italic text</td>
</tr>
<tr>
<td><code>underline</code></td>
<td>Underlined text</td>
</tr>
<tr>
<td><code>invert</code></td>
<td>Swaps the foreground and background colors</td>
</tr>
<tr>
<td><code>conceal</code></td>
<td>Hides the text</td>
</tr>
<tr>
<td><code>slowblink</code></td>
<td>Makes text blink slowly</td>
</tr>
<tr>
<td><code>rapidblink</code></td>
<td>Makes text blink</td>
</tr>
<tr>
<td><code>strikethrough</code></td>
<td>Shows text with a horizontal line through the center</td>
</tr>
</table>

View File

@@ -18,6 +18,18 @@ $thebackground: $gray-200;
display: inline-block;
width: 60px;
height: 15px;
border: 2px solid #000000;
}
#topnav {
padding: 0px;
margin: 0px;
}
#topnav .container {
padding-top: 0px !important;
padding-bottom: 0px !important;
margin-bottom: 0px;
}
@media screen {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,34 @@
$(document).ready(function () {
$('.filter').each(function () {
let input = this;
let table = document.getElementById(input.dataset.table);
input.onkeyup = function (event) {
if (event.key === "Enter") {
event.preventDefault();
event.stopPropagation();
return false;
}
let value = input.value.toUpperCase();
let rows = table.getElementsByClassName('search-row');
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
let match =
new RegExp(value, "i").test(row.textContent) ||
value === '';
if (match) {
row.style.display = 'table-row';
} else {
row.style.display = 'none';
}
}
}; // keyup
})
}); // ready

View File

@@ -0,0 +1,12 @@
Title: CLI
Order: 10
---
<h1>Sections</h1>
<ul>
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
{
<li>@Html.DocumentLink(child)</li>
}
</ul>

View File

@@ -0,0 +1,121 @@
Title: Introduction
Order: 1
---
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely
opinionated in what it does, it tries to follow established industry conventions, and draws
its inspiration from applications you use everyday.
# How does it work?
The underlying philosophy behind `Spectre.Console.Cli` is to rely on the .NET type system to
declare the commands, but tie everything together via composition.
Imagine the following command structure:
* dotnet *(executable)*
* add `[PROJECT]`
* package `<PACKAGE_NAME>` --version `<VERSION>`
* reference `<PROJECT_REFERENCE>`
For this I would like to implement the commands (the different levels in the tree that
executes something) separately from the settings (the options, flags and arguments),
which I want to be able to inherit from each other.
## Specify the settings
We start by creating some settings that represents the options, flags and arguments
that we want to act upon.
```csharp
public class AddSettings : CommandSettings
{
[CommandArgument(0, "[PROJECT]")]
public string Project { get; set; }
}
public class AddPackageSettings : AddSettings
{
[CommandArgument(0, "<PACKAGE_NAME>")]
public string PackageName { get; set; }
[CommandOption("-v|--version <VERSION>")]
public string Version { get; set; }
}
public class AddReferenceSettings : AddSettings
{
[CommandArgument(0, "<PROJECT_REFERENCE>")]
public string ProjectReference { get; set; }
}
```
## Specify the commands
Now it's time to specify the commands that act on the settings we created
in the previous step.
```csharp
public class AddPackageCommand : Command<AddPackageSettings>
{
public override int Execute(CommandContext context, AddPackageSettings settings)
{
// Omitted
return 0;
}
}
public class AddReferenceCommand : Command<AddReferenceSettings>
{
public override int Execute(CommandContext context, AddReferenceSettings settings)
{
// Omitted
return 0;
}
}
```
You can use `AsyncCommand` if you need async support.
## Let's tie it together
Now when we have our commands and settings implemented, we can compose a command tree
that tells the parser how to interpret user input.
```csharp
using Spectre.Console.Cli;
namespace MyApp
{
public static class Program
{
public static int Main(string[] args)
{
var app = new CommandApp();
app.Configure(config =>
{
config.AddBranch<AddSettings>("add", add =>
{
add.AddCommand<AddPackageCommand>("package");
add.AddCommand<AddReferenceCommand>("reference");
});
});
return app.Run(args);
}
}
}
```
# So why this way?
Now you might wonder, why do things like this? Well, for starters the different parts
of the application are separated, while still having the option to share things like options,
flags and arguments between them.
This make the resulting code very clean and easy to navigate, not to mention to unit test.
And most importantly at all, the type system guides me to do the right thing. I can't configure
commands in non-compatible ways, and if I want to add a new top-level `add-package` command
(or move the command completely), it's just a single line to change. This makes it easy to
experiment and makes the CLI experience a first class citizen of your application.

View File

@@ -0,0 +1,47 @@
Title: Migrate from Spectre.Cli
Order: 2
---
The functionality in `Spectre.Cli` has been moved into the `Spectre.Console`
library. If you're using `Spectre.Cli`, you will need to migrate to ensure
that you get updates or fixes.
## 1. Remove Spectre.Cli NuGet package
Start with removing the `Spectre.Cli` package reference from your project(s).
```text
> dotnet remove package Spectre.Cli
```
## 2. Add Spectre.Console NuGet package
Add the [Spectre.Console](https://www.nuget.org/packages/spectre.console) NuGet package to your project(s).
```text
> dotnet add package Spectre.Console
```
## 3. Change using statements
Change all using statements from `Spectre.Cli`
to `Spectre.Console.CLi`.
```diff
- using Spectre.Cli;
+ using Spectre.Console.Cli;
```
# Breaking Changes
In the process of moving `Spectre.Cli`, there have been some minor breaking changes.
## Spectre.Cli.Exceptions namespace moved
All exceptions have been moved from the `Spectre.Cli.Exceptions` namespace to
the `Spectre.Console.Cli` namespace.
```diff
- using Spectre.Cli.Exceptions;
+ using Spectre.Console.Cli;
```

View File

@@ -1,16 +0,0 @@
Title: Colors
Order: 2
---
The following is a list of the standard 8-bit colors supported in terminals.
Note that the first 16 colors are generally defined by the system or your terminal software, and may not display exactly as rendered here.
# Usage
You can either use the colors in code, such as `new Style(foreground: Color.Maroon)` or
in markup text such as `AnsiConsole.Markup("[maroon on blue]Hello[/]")`.
# Standard colors
<?# ColorTable /?>

View File

@@ -1,6 +0,0 @@
Title: Console API
Order: 2
Hidden: True
---
__To be written__

View File

@@ -1,6 +0,0 @@
Title: Grids
Order: 4
Hidden: True
---
__To be written__

View File

@@ -1,6 +0,0 @@
Title: Panels
Order: 5
Hidden: True
---
__To be written__

View File

@@ -1,6 +0,0 @@
Title: Tables
Order: 3
Hidden: True
---
__To be written__

52
docs/input/exceptions.md Normal file
View File

@@ -0,0 +1,52 @@
Title: Exceptions
Order: 3
---
Exceptions aren't always readable when viewed in the terminal.
You can make exception a bit more readable by using the `WriteException` method.
```csharp
AnsiConsole.WriteException(ex);
```
<img src="assets/images/exception.png" style="max-width: 100%;">
## Shortening parts
You can also shorten specific parts of the exception to make it even
more readable, and make paths clickable hyperlinks. Whether or not
the hyperlinks are clickable is up to the terminal.
```csharp
AnsiConsole.WriteException(ex,
ExceptionFormats.ShortenPaths | ExceptionFormats.ShortenTypes |
ExceptionFormats.ShortenMethods | ExceptionFormats.ShowLinks);
```
<img src="assets/images/compact_exception.png" style="max-width: 100%;">
## Customizing exception output
In addition to shorten specific part of the exception, you can
also override the default styling.
```csharp
AnsiConsole.WriteException(ex, 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),
}
});
```
<img src="assets/images/custom_exception.png" style="max-width: 100%;">

View File

@@ -1,84 +0,0 @@
Title: Start
NoContainer: true
---
@section Splash {
<div id="hero" class="jumbotron jumbotron-fluid mb-0">
<div class="container">
<div class="display-4 text-white">Spectre.Console</div>
<p class="lead text-white">
A .NET Standard library that makes it easier to create beautiful console applications.
<br /><br />
<a class="btn btn-primary" href="/spectre.console/docs" role="button">Take me to the documentation</a>
</p>
</div>
</div>
}
@* <div class="container py-3">
<div class="row">
<div class="col-sm py-3">
<div class="row">
<div class="col-md-2">
<i class="fad fa-heartbeat fa-2x icon-md-100 icon-theme"></i>
</div>
<div class="col-md-10">
<h3 class="font-weight-bold font-size-base text-dark mb-2">A beautiful console</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean elementum est lorem, at auctor nibh rhoncus eget.
Ut lorem leo, aliquet sit amet tortor vitae, aliquet eleifend dui.
Etiam lectus diam, maximus a pretium a, lacinia in augue.
</p>
</div>
</div>
</div>
<div class="col-sm py-3">
<div class="row">
<div class="col-md-2">
<i class="fad fa-code fa-2x icon-md-100 icon-theme"></i>
</div>
<div class="col-md-10">
<h3 class="font-weight-bold font-size-base text-dark mb-2">Rich formatting language</h3>
<p>
Donec at rutrum turpis. Etiam tempor sed ex quis pharetra.
Suspendisse ullamcorper at magna ac efficitur. Nulla ornare,
lectus feugiat ornare ultricies, nunc lorem maximus ipsum,
nec accumsan eros tellus quis ante
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm py-3">
<div class="row">
<div class="col-md-2">
<i class="fad fa-cogs fa-2x icon-md-100 icon-theme"></i>
</div>
<div class="col-md-10">
<h3 class="font-weight-bold font-size-base text-dark mb-2">Configurable</h3>
<p>
Suspendisse vel condimentum tortor. Fusce tempus ligula ut eros finibus,
nec fermentum ipsum hendrerit. Proin eu diam in tortor vestibulum bibendum.
Integer tincidunt felis eu urna pulvinar vehicula.
</p>
</div>
</div>
</div>
<div class="col-sm py-3">
<div class="row">
<div class="col-md-2">
<i class="fad fa-search fa-2x icon-md-100 icon-theme"></i>
</div>
<div class="col-md-10">
<h3 class="font-weight-bold font-size-base text-dark mb-2">Find problems quickly</h3>
<p>
Aliquam nec nisl ullamcorper, aliquam mauris sit amet, sagittis orci.
Aenean sapien dui, eleifend eget sapien nec, tristique accumsan tortor.
Quisque ex quam, rhoncus sagittis consequat id, euismod sit amet dolor.
</p>
</div>
</div>
</div>
</div>
</div> *@

View File

@@ -1,4 +1,4 @@
Title: Welcome
Title: Welcome
Order: 0
---
@@ -13,14 +13,14 @@ for Python written by Will McGugan.
* Supports tables, grids, panels, and a [Rich](https://github.com/willmcgugan/rich)
inspired markup language.
* Supports the most common
[SRG parameters](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters)
[SGR parameters](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters)
when it comes to text styling such as bold, dim, italic, underline, strikethrough,
and blinking text.
* Supports `3`/`4`/`8`/`24`-bit colors in the terminal.
The library will detect the capabilities of the current terminal
and downgrade colors as needed.
## Example
## Examples
<img width="100%"
src="https://github.com/spectresystems/spectre.console/raw/main/resources/gfx/screenshots/example.png" />
<img src="./assets/images/example.png" style="max-width: 100%; margin-top: 15px; margin-bottom: 25px;" />
<img src="./assets/images/table.gif" style="max-width: 100%;" />

View File

@@ -0,0 +1,12 @@
Title: Live Displays
Order: 4
---
<h1>Sections</h1>
<ul>
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
{
<li>@Html.DocumentLink(child)</li>
}
</ul>

View File

@@ -0,0 +1,86 @@
Title: Progress
Order: 5
RedirectFrom: progress
---
Spectre.Console can display information about long running tasks in the console.
<img src="../assets/images/progress.png" style="max-width: 100%;margin-bottom:20px;">
<div class="alert alert-warning" role="alert">
<i class="fas fa-exclamation-triangle icon-web"></i> The progress display is not
thread safe, and using it together with other interactive components such as
prompts, status displays or other progress displays are not supported.
</div>
If the current terminal isn't considered "interactive", such as when running
in a continuous integration system, or the terminal can't display
ANSI control sequence, any progress will be displayed in a simpler way.
<img src="../assets/images/progress_fallback.png" style="max-width: 100%;">
# Usage
```csharp
// Synchronous
AnsiConsole.Progress()
.Start(ctx =>
{
// Define tasks
var task1 = ctx.AddTask("[green]Reticulating splines[/]");
var task2 = ctx.AddTask("[green]Folding space[/]");
while(!ctx.IsFinished)
{
task1.Increment(1.5);
task2.Increment(0.5);
}
});
```
## Asynchronous progress
If you prefer to use async/await, you can use `StartAsync` instead of `Start`.
```csharp
// Asynchronous
await AnsiConsole.Progress()
.StartAsync(async ctx =>
{
// Define tasks
var task1 = ctx.AddTask("[green]Reticulating splines[/]");
var task2 = ctx.AddTask("[green]Folding space[/]");
while (!ctx.IsFinished)
{
// Simulate some work
await Task.Delay(250);
// Increment
task1.Increment(1.5);
task2.Increment(0.5);
}
});
```
# Configure
```csharp
// Asynchronous
AnsiConsole.Progress()
.AutoRefresh(false) // Turn off auto refresh
.AutoClear(false) // Do not remove the task list when done
.HideCompleted(false) // Hide tasks as they are completed
.Columns(new ProgressColumn[]
{
new TaskDescriptionColumn(), // Task description
new ProgressBarColumn(), // Progress bar
new PercentageColumn(), // Percentage
new RemainingTimeColumn(), // Remaining time
new SpinnerColumn(), // Spinner
})
.Start(ctx =>
{
// Omitted
});
```

67
docs/input/live/status.md Normal file
View File

@@ -0,0 +1,67 @@
Title: Status
Order: 6
RedirectFrom: status
---
Spectre.Console can display information about long running tasks in the console.
<img src="../assets/images/status.gif" style="max-width: 100%;margin-bottom:20px;">
<div class="alert alert-warning" role="alert">
<i class="fas fa-exclamation-triangle icon-web"></i> The status display is not
thread safe, and using it together with other interactive components such as
prompts, progress displays or other status displays are not supported.
</div>
If the current terminal isn't considered "interactive", such as when running
in a continuous integration system, or the terminal can't display
ANSI control sequence, any progress will be displayed in a simpler way.
# Usage
```csharp
// Synchronous
AnsiConsole.Status()
.Start("Thinking...", ctx =>
{
// Simulate some work
AnsiConsole.MarkupLine("Doing some work...");
Thread.Sleep(1000);
// Update the status and spinner
ctx.Status("Thinking some more");
ctx.Spinner(Spinner.Known.Star);
ctx.SpinnerStyle(Style.Parse("green"));
// Simulate some work
AnsiConsole.MarkupLine("Doing some more work...");
Thread.Sleep(2000);
});
```
## Asynchronous progress
If you prefer to use async/await, you can use `StartAsync` instead of `Start`.
```csharp
// Asynchronous
await AnsiConsole.Status()
.StartAsync("Thinking...", async ctx =>
{
// Omitted
});
```
# Configure
```csharp
AnsiConsole.Status()
.AutoRefresh(false)
.Spinner(Spinner.Known.Star)
.SpinnerStyle(Style.Parse("green bold"))
.Start("Thinking...", ctx =>
{
// Omitted
ctx.Refresh();
});
```

92
docs/input/markup.md Normal file
View File

@@ -0,0 +1,92 @@
Title: Markup
Order: 2
---
The class `Markup` allows you to output rich text to the console.
# Syntax
Console markup uses a syntax inspired by bbcode. If you write the style (see [Styles](xref:styles))
in square brackets, e.g. `[bold red]`, that style will apply until it is closed with a `[/]`.
```csharp
AnsiConsole.Render(new Markup("[bold yellow]Hello[/] [red]World![/]"));
```
The `Markup` class implements `IRenderable` which means that you
can use this in tables, grids, and panels. Most classes that support
rendering of `IRenderable` also have overloads for rendering rich text.
```csharp
var table = new Table();
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
table.AddColumn(new TableColumn("[blue]Bar[/]"));
AnsiConsole.Render(table);
```
# Convenience methods
There is also convenience methods on `AnsiConsole` that can be used
to write markup text to the console without instantiating a new `Markup`
instance.
```csharp
AnsiConsole.Markup("[underline green]Hello[/] ");
AnsiConsole.MarkupLine("[bold]World[/]");
```
# Escaping format characters
To output a `[` you use `[[`, and to output a `]` you use `]]`.
```csharp
AnsiConsole.Markup("[[Hello]] "); // [Hello]
AnsiConsole.Markup("[red][[World]][/]"); // [World]
```
You can also use the `EscapeMarkup` extension method.
```csharp
AnsiConsole.Markup("[red]{0}[/]", "Hello [World]".EscapeMarkup());
```
You can also use the `Markup.Escape` method.
```csharp
AnsiConsole.Markup("[red]{0}[/]", Markup.Escape("Hello [World]"));
```
# Setting background color
You can set the background color in markup by prefixing the color with
`on`.
```csharp
AnsiConsole.Markup("[bold yellow on blue]Hello[/]");
AnsiConsole.Markup("[default on blue]World[/]");
```
# Rendering emojis
To output an emoji as part of markup, you can use emoji shortcodes.
```csharp
AnsiConsole.Markup("Hello :globe_showing_europe_africa:!");
```
For a list of emoji, see the [Emojis](xref:emojis) appendix section.
# Colors
In the examples above, all colors was referenced by their name,
but you can also use the hex or rgb representation for colors in markdown.
```csharp
AnsiConsole.Markup("[red]Foo[/] ");
AnsiConsole.Markup("[#ff0000]Bar[/] ");
AnsiConsole.Markup("[rgb(255,0,0)]Baz[/] ");
```
For a list of colors, see the [Colors](xref:colors) appendix section.
# Styles
For a list of styles, see the [Styles](xref:styles) appendix section.

View File

@@ -0,0 +1,12 @@
Title: Prompts
Order: 5
---
<h1>Sections</h1>
<ul>
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
{
<li>@Html.DocumentLink(child)</li>
}
</ul>

View File

@@ -0,0 +1,40 @@
Title: Multi Selection
Order: 3
---
The `MultiSelectionPrompt` can be used when you want the user to select
one or many items from a provided list.
<img src="../assets/images/multiselection.gif" style="width: 100%;" />
<div class="alert alert-warning" role="alert" style="margin-top:20px;">
<i class="fas fa-exclamation-triangle icon-web"></i> The use of prompts
insides status or progress displays is not supported.
</div>
# Usage
```csharp
// Ask for the user's favorite fruits
var fruits = AnsiConsole.Prompt(
new MultiSelectionPrompt<string>()
.Title("What are your [green]favorite fruits[/]?")
.NotRequired() // Not required to have a favorite fruit
.PageSize(10)
.MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
.InstructionsText(
"[grey](Press [blue]<space>[/] to toggle a fruit, " +
"[green]<enter>[/] to accept)[/]")
.AddChoice("Apple")
.AddChoices(new[] {
"Apricot", "Avocado",
"Banana", "Blackcurrant", "Blueberry",
"Cherry", "Cloudberry", "Cocunut",
}));
// Write the selected fruits to the terminal
foreach (string fruit in fruits)
{
AnsiConsole.WriteLine(fruit);
}
```

View File

@@ -0,0 +1,33 @@
Title: Selection
Order: 1
---
The `SelectionPrompt` can be used when you want the user to select
a single item from a provided list.
<img src="../assets/images/selection.gif" style="width: 100%;" />
<div class="alert alert-warning" role="alert" style="margin-top:20px;">
<i class="fas fa-exclamation-triangle icon-web"></i> Using prompts inside
status or progress displays, are not supported.
</div>
# Usage
```csharp
// Ask for the user's favorite fruit
var fruit = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("What's your [green]favorite fruit[/]?")
.PageSize(10)
.MoreChoicesText("[grey](Move up and down to reveal more fruits)[/]")
.AddChoice("Apple")
.AddChoices(new[] {
"Apricot", "Avocado",
"Banana", "Blackcurrant", "Blueberry",
"Cherry", "Cloudberry", "Cocunut",
}));
// Echo the fruit back to the terminal
AnsiConsole.WriteLine($"I agree. {fruit} is tasty!");
```

105
docs/input/prompts/text.md Normal file
View File

@@ -0,0 +1,105 @@
Title: Text prompt
Order: 0
RedirectFrom: prompt
---
Sometimes you want to get some input from the user, and for this
you can use the `Prompt<TResult>`.
<div class="alert alert-warning" role="alert">
<i class="fas fa-exclamation-triangle icon-web"></i> The use of prompts
insides status or progress displays is not supported.
</div>
# Confirmation
```csharp
if (!AnsiConsole.Confirm("Run example?"))
{
return;
}
```
```text
Run example? [y/n] (y): _
```
# Simple
```csharp
// Ask for the user's name
string name = AnsiConsole.Ask<string>("What's your [green]name[/]?");
// Ask for the user's age
int age = AnsiConsole.Ask<int>("What's your [green]age[/]?");
```
```text
What's your name? Patrik
What's your age? 37
```
# Choices
```csharp
var fruit = AnsiConsole.Prompt(
new TextPrompt<string>("What's your [green]favorite fruit[/]?")
.InvalidChoiceMessage("[red]That's not a valid fruit[/]")
.DefaultValue("Orange")
.AddChoice("Apple")
.AddChoice("Banana")
.AddChoice("Orange"));
```
```text
What's your favorite fruit? [Apple/Banana/Orange] (Orange): _
```
# Validation
```csharp
var age = AnsiConsole.Prompt(
new TextPrompt<int>("What's the secret number?")
.Validate(age =>
{
return age switch
{
< 99 => ValidationResult.Error("[red]Too low[/]"),
> 99 => ValidationResult.Error("[red]Too high[/]"),
_ => ValidationResult.Success(),
};
}));
```
```text
What's the secret number? 32
Too low
What's the secret number? 102
Too high
What's the secret number? _
```
# Secrets
```csharp
var password = AnsiConsole.Prompt(
new TextPrompt<string>("Enter [green]password[/]")
.PromptStyle("red")
.Secret());
```
```text
Enter password: ************_
```
# Optional
```csharp
var color = AnsiConsole.Prompt(
new TextPrompt<string>("[grey][[Optional]][/] [green]Favorite color[/]?")
.AllowEmpty());
```
```text
[Optional] Favorite color? _
```

View File

@@ -5,7 +5,7 @@ Order: 1
The fastest way of getting started using Spectre.Console is
to install the NuGet package.
```shell
```text
> dotnet add package Spectre.Console
```

20
docs/input/sponsors.md Normal file
View File

@@ -0,0 +1,20 @@
Title: Sponsors
Order: 0
---
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
Spectre.Console to show their support and to ensure the longevity of the project.
* [Rodney Littles II](https://github.com/RLittlesII)
* [Martin Björkström](https://github.com/bjorkstromm)
* [Dave Glick](https://github.com/daveaglick)
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
* [Andrew McClenaghan](https://github.com/andymac4182)
* [C. Augusto Proiete](https://github.com/augustoproiete)
* [Viktor Elofsson](https://github.com/vktr)
* [Steven Knox](https://github.com/stevenknox)
* [David Pendray](https://github.com/dpen2000)
* [Elmah.io](https://github.com/elmahio)
I really appreciate it.
**Thank you very much!**

View File

@@ -0,0 +1,75 @@
Title: Bar Chart
Order: 20
---
Use `BarChart` to render bar charts to the console.
<img src="../assets/images/barchart.png" style="width: 100%;" />
# Usage
## Basic usage
```csharp
AnsiConsole.Render(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));
```
## Add items with converter
```csharp
// Create a list of fruits
var items = new List<(string Label, double Value)>
{
("Apple", 12),
("Orange", 54),
("Banana", 33),
};
// Render bar chart
AnsiConsole.Render(new BarChart()
.Width(60)
.Label("[green bold underline]Number of fruits[/]")
.CenterLabel()
.AddItems(items, (item) => new BarChartItem(
item.Label, item.Value, Color.Yellow)));
```
## Add items implementing IBarChartItem
```csharp
public sealed class Fruit : IBarChartItem
{
public string Label { get; set; }
public double Value { get; set; }
public Color? Color { get; set; }
public Fruit(string label, double value, Color? color = null)
{
Label = label;
Value = value;
Color = color;
}
}
// Create a list of fruits
var items = new List<Fruit>
{
new Fruit("Apple", 12, Color.Yellow),
new Fruit("Orange", 54, Color.Red),
new Fruit("Banana", 33, Color.Green),
};
// Render bar chart
AnsiConsole.Render(new BarChart()
.Width(60)
.Label("[green bold underline]Number of fruits[/]")
.CenterLabel()
.AddItem(new Fruit("Mango", 3))
.AddItems(items));
```

View File

@@ -0,0 +1,121 @@
Title: Calendar
Order: 40
RedirectFrom: calendar
---
The `Calendar` is used to render a calendar to the terminal.
# Usage
To render a calendar, create a `Calendar` instance with a target date.
```csharp
var calendar = new Calendar(2020,10);
AnsiConsole.Render(calendar);
```
```text
2020 October
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ 1 │ 2 │ 3 │
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │
│ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │
│ │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
```
## Culture
You can set the calendar's culture to show localized weekdays.
```csharp
var calendar = new Calendar(2020,10);
calendar.Culture("ja-JP");
AnsiConsole.Render(calendar);
```
```text
Oktober 2020
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ Mån │ Tis │ Ons │ Tor │ Fre │ Lör │ Sön │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ 1 │ 2 │ 3 │ 4 │
│ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11* │
│ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │
│ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │
│ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ │
│ │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
```
## Header
You can hide the calendar header.
```csharp
var calendar = new Calendar(2020,10);
calendar.ShowHeader();
AnsiConsole.Render(calendar);
```
```text
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ 1 │ 2 │ 3 │
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │
│ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │
│ │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
```
You can set the header style of the calendar.
```csharp
var calendar = new Calendar(2020, 10);
calendar.HeaderStyle(Style.Parse("blue bold"));
AnsiConsole.Render(calendar);
```
## Calendar Events
You can add an event to the calendar.
If a date has an event associated with it, the date gets highlighted in the calendar.
```csharp
var calendar = new Calendar(2020,10);
calendar.AddCalendarEvent(2020, 10, 11);
AnsiConsole.Render(calendar);
```
```text
2020 October
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ │ │ 1 │ 2 │ 3 │
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │
│ 11* │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │
│ │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
```
### Highlight style
You can set the highlight style for a calendar event via `SetHighlightStyle`.
```csharp
var calendar = new Calendar(2020, 10);
calendar.AddCalendarEvent(2020, 10, 11);
calendar.HighlightStyle(Style.Parse("yellow bold"));
AnsiConsole.Render(calendar);
```

View File

@@ -0,0 +1,106 @@
Title: Canvas Image
Order: 70
---
To add [ImageSharp](https://github.com/SixLabors/ImageSharp) superpowers to
your console application to draw images, you will need to install
the [Spectre.Console.ImageSharp](https://www.nuget.org/packages/Spectre.Console.ImageSharp) NuGet package.
```text
> dotnet add package Spectre.Console.ImageSharp
```
# Loading images
Once you've added the `Spectre.Console.ImageSharp` NuGet package,
you can create a new instance of `CanvasImage` to draw images to the console.
```csharp
// Load an image
var image = new CanvasImage("cake.png");
// Set the max width of the image.
// If no max width is set, the image will take
// up as much space as there is available.
image.MaxWidth(16);
// Render the image to the console
AnsiConsole.Render(image);
```
## Result
<pre style="font-size:90%;font-family:consolas,'Courier New',monospace;line-height: normal; padding: 0px;background-color: #222222; padding: 20px;">
<span> </span><span style="background-color: #542813"> </span><span style="background-color: #572F1B"> </span><span style="background-color: #4E1F09"> </span><span style="background-color: #5B3826"> </span><span style="background-color: #5E3A29"> </span><span style="background-color: #532611"> </span><span> </span>
<span> </span><span style="background-color: #562E1B"> </span><span style="background-color: #634737"> </span><span style="background-color: #562E1A"> </span><span style="background-color: #5D4132"> </span><span style="background-color: #6D584B"> </span><span style="background-color: #624332"> </span><span style="background-color: #562B17"> </span><span> </span>
<span> </span><span style="background-color: #512714"> </span><span style="background-color: #654E40"> </span><span style="background-color: #705243"> </span><span style="background-color: #745749"> </span><span style="background-color: #6D5B4F"> </span><span style="background-color: #715E52"> </span><span style="background-color: #644636"> </span><span style="background-color: #6A4433"> </span><span style="background-color: #542916"> </span><span style="background-color: #431C0B"> </span><span> </span>
<span> </span><span style="background-color: #491E0A"> </span><span style="background-color: #5C3523"> </span><span style="background-color: #695346"> </span><span style="background-color: #705C4F"> </span><span style="background-color: #654838"> </span><span style="background-color: #654A3A"> </span><span style="background-color: #726154"> </span><span style="background-color: #715D50"> </span><span style="background-color: #B8A79F"> </span><span style="background-color: #AE988F"> </span><span style="background-color: #6F4A39"> </span><span style="background-color: #441906"> </span><span> </span>
<span> </span><span style="background-color: #532916"> </span><span style="background-color: #8A6C5E"> </span><span style="background-color: #C2B3AB"> </span><span style="background-color: #8B786E"> </span><span style="background-color: #6B584C"> </span><span style="background-color: #695143"> </span><span style="background-color: #6C5648"> </span><span style="background-color: #6F5D51"> </span><span style="background-color: #816A55"> </span><span style="background-color: #E7E1DA"> </span><span style="background-color: #F9F5EE"> </span><span style="background-color: #BAA593"> </span><span style="background-color: #61381F"> </span><span> </span>
<span style="background-color: #421C0A"> </span><span style="background-color: #603826"> </span><span style="background-color: #9E8479"> </span><span style="background-color: #E2DAD6"> </span><span style="background-color: #FBF9F6"> </span><span style="background-color: #F0EADF"> </span><span style="background-color: #C4B59D"> </span><span style="background-color: #9D8663"> </span><span style="background-color: #786451"> </span><span style="background-color: #705D4E"> </span><span style="background-color: #BFA052"> </span><span style="background-color: #FEE88B"> </span><span style="background-color: #FDE580"> </span><span style="background-color: #E2C362"> </span><span style="background-color: #794E1D"> </span><span> </span>
<span style="background-color: #4B1D05"> </span><span style="background-color: #A6844C"> </span><span style="background-color: #E9D595"> </span><span style="background-color: #F1DC92"> </span><span style="background-color: #F5DD83"> </span><span style="background-color: #FBE278"> </span><span style="background-color: #FFE36E"> </span><span style="background-color: #F1D25E"> </span><span style="background-color: #866F4B"> </span><span style="background-color: #726256"> </span><span style="background-color: #967945"> </span><span style="background-color: #F5D456"> </span><span style="background-color: #F8D756"> </span><span style="background-color: #E1BE4A"> </span><span style="background-color: #7D511B"> </span><span> </span>
<span style="background-color: #4F2005"> </span><span style="background-color: #C9A441"> </span><span style="background-color: #FFE05C"> </span><span style="background-color: #FEDF5B"> </span><span style="background-color: #FCDC59"> </span><span style="background-color: #F7D555"> </span><span style="background-color: #E5C04A"> </span><span style="background-color: #795E3B"> </span><span style="background-color: #726256"> </span><span style="background-color: #755F4C"> </span><span style="background-color: #A17124"> </span><span style="background-color: #AE7414"> </span><span style="background-color: #AE791D"> </span><span style="background-color: #794D18"> </span><span> </span>
<span style="background-color: #4E1F04"> </span><span style="background-color: #B78D31"> </span><span style="background-color: #DDB33E"> </span><span style="background-color: #D0A132"> </span><span style="background-color: #C28F25"> </span><span style="background-color: #B67E1A"> </span><span style="background-color: #AC7111"> </span><span style="background-color: #9E610A"> </span><span style="background-color: #5F3212"> </span><span style="background-color: #6A574B"> </span><span style="background-color: #726256"> </span><span style="background-color: #744D2A"> </span><span style="background-color: #955401"> </span><span style="background-color: #8C5106"> </span><span style="background-color: #5F310C"> </span><span> </span>
<span style="background-color: #4B1A00"> </span><span style="background-color: #854903"> </span><span style="background-color: #9B5A02"> </span><span style="background-color: #995700"> </span><span style="background-color: #935200"> </span><span style="background-color: #592402"> </span><span style="background-color: #5B3F30"> </span><span style="background-color: #726256"> </span><span style="background-color: #705A4A"> </span><span style="background-color: #844C0C"> </span><span style="background-color: #824400"> </span><span style="background-color: #4C1B00"> </span><span> </span>
<span style="background-color: #4B1A00"> </span><span style="background-color: #824500"> </span><span style="background-color: #995700"> </span><span style="background-color: #935200"> </span><span style="background-color: #592300"> </span><span style="background-color: #4F2411"> </span><span style="background-color: #6B584C"> </span><span style="background-color: #736256"> </span><span style="background-color: #734E2C"> </span><span style="background-color: #7C4101"> </span><span style="background-color: #4C1B00"> </span><span> </span>
<span style="background-color: #4B1A00"> </span><span style="background-color: #824500"> </span><span style="background-color: #995700"> </span><span style="background-color: #935200"> </span><span style="background-color: #592300"> </span><span style="background-color: #4A1902"> </span><span style="background-color: #5C4031"> </span><span style="background-color: #726256"> </span><span style="background-color: #705B4B"> </span><span style="background-color: #6A390F"> </span><span style="background-color: #4C1A00"> </span><span> </span>
<span style="background-color: #4B1A00"> </span><span style="background-color: #824500"> </span><span style="background-color: #995700"> </span><span style="background-color: #935200"> </span><span style="background-color: #592300"> </span><span style="background-color: #4A1700"> </span><span style="background-color: #4F2512"> </span><span style="background-color: #6B594D"> </span><span style="background-color: #736256"> </span><span style="background-color: #634432"> </span><span style="background-color: #4C1D08"> </span><span> </span>
<span style="background-color: #4B1A00"> </span><span style="background-color: #814400"> </span><span style="background-color: #955400"> </span><span style="background-color: #915100"> </span><span style="background-color: #8C4D00"> </span><span style="background-color: #864800"> </span><span style="background-color: #7F4301"> </span><span style="background-color: #743A01"> </span><span style="background-color: #521E01"> </span><span style="background-color: #4A1700"> </span><span style="background-color: #4A1902"> </span><span style="background-color: #5D4132"> </span><span style="background-color: #726256"> </span><span style="background-color: #6F5B4E"> </span><span style="background-color: #5D3A28"> </span><span style="background-color: #53220C"> </span>
<span style="background-color: #471801"> </span><span style="background-color: #642D01"> </span><span style="background-color: #6B3301"> </span><span style="background-color: #642E02"> </span><span style="background-color: #5D2902"> </span><span style="background-color: #542203"> </span><span style="background-color: #4C1C04"> </span><span style="background-color: #461905"> </span><span style="background-color: #4A1C07"> </span><span style="background-color: #4C1A03"> </span><span style="background-color: #4B1801"> </span><span style="background-color: #502613"> </span><span style="background-color: #69564A"> </span><span style="background-color: #705F54"> </span><span style="background-color: #604232"> </span><span style="background-color: #51200A"> </span>
<span style="background-color: #411806"> </span><span style="background-color: #431A07"> </span><span style="background-color: #411D0D"> </span><span> </span><span style="background-color: #4D1B05"> </span><span style="background-color: #4D1D07"> </span><span style="background-color: #533324"> </span><span style="background-color: #583E30"> </span><span style="background-color: #53301F"> </span><span style="background-color: #53230D"> </span>
</pre>
# Manipulating images
You can take full advantage of [ImageSharp](https://github.com/SixLabors/ImageSharp)
and manipulate images directly via it's [Processing API](https://docs.sixlabors.com/api/ImageSharp/SixLabors.ImageSharp.Processing.html).
```csharp
// Load an image
var image = new CanvasImage("cake.png");
image.MaxWidth(32);
// Set a sampler that will be used when scaling the image.
image.BilinearResampler();
// Mutate the image using ImageSharp
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
// Render the image to the console
AnsiConsole.Render(image);
```
## Result
<pre style="font-size:90%;font-family:consolas,'Courier New',monospace;line-height: normal; padding: 0px;background-color: #222222; padding: 20px;">
<span> </span><span style="background-color: #282828"> </span><span style="background-color: #222222"> </span><span style="background-color: #232323"> </span><span style="background-color: #353535"> </span><span style="background-color: #4B4B4B"> </span><span style="background-color: #595959"> </span><span style="background-color: #3B3B3B"> </span><span style="background-color: #202020"> </span><span style="background-color: #191919"> </span><span> </span>
<span> </span><span style="background-color: #343434"> </span><span style="background-color: #2B2B2B"> </span><span style="background-color: #292929"> </span><span style="background-color: #272727"> </span><span style="background-color: #252525"> </span><span style="background-color: #292929"> </span><span style="background-color: #555555"> </span><span style="background-color: #929292"> </span><span style="background-color: #C7C7C7"> </span><span style="background-color: #E5E5E5"> </span><span style="background-color: #F0F0F0"> </span><span style="background-color: #E4E4E4"> </span><span style="background-color: #A8A8A8"> </span><span style="background-color: #515151"> </span><span style="background-color: #202020"> </span><span style="background-color: #191919"> </span><span> </span>
<span> </span><span style="background-color: #2E2E2E"> </span><span style="background-color: #2B2B2B"> </span><span style="background-color: #333333"> </span><span style="background-color: #373737"> </span><span style="background-color: #3C3C3C"> </span><span style="background-color: #414141"> </span><span style="background-color: #474747"> </span><span style="background-color: #4B4B4B"> </span><span style="background-color: #454545"> </span><span style="background-color: #828282"> </span><span style="background-color: #E0E0E0"> </span><span style="background-color: #FFFFFF"> </span><span style="background-color: #FCFCFC"> </span><span style="background-color: #DEDEDE"> </span><span style="background-color: #DADADA"> </span><span style="background-color: #BCBCBC"> </span><span style="background-color: #515151"> </span><span style="background-color: #202020"> </span><span style="background-color: #191919"> </span><span> </span>
<span> </span><span style="background-color: #272727"> </span><span style="background-color: #414141"> </span><span style="background-color: #5C5C5C"> </span><span style="background-color: #616161"> </span><span style="background-color: #636363"> </span><span style="background-color: #656565"> </span><span style="background-color: #666666"> </span><span style="background-color: #656565"> </span><span style="background-color: #5A5A5A"> </span><span style="background-color: #707070"> </span><span style="background-color: #F3F3F3"> </span><span style="background-color: #FFFFFF"> </span><span style="background-color: #F0F0F0"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #BABABA"> </span><span style="background-color: #505050"> </span><span style="background-color: #202020"> </span><span style="background-color: #1B1B1B"> </span><span> </span>
<span> </span><span style="background-color: #242424"> </span><span style="background-color: #3B3B3B"> </span><span style="background-color: #545454"> </span><span style="background-color: #606060"> </span><span style="background-color: #656565"> </span><span style="background-color: #666666"> </span><span style="background-color: #606060"> </span><span style="background-color: #575757"> </span><span style="background-color: #E8E8E8"> </span><span style="background-color: #F6F6F6"> </span><span style="background-color: #E1E1E1"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #D9D9D9"> </span><span style="background-color: #A0A0A0"> </span><span style="background-color: #989898"> </span><span style="background-color: #4E4E4E"> </span><span style="background-color: #222222"> </span><span> </span>
<span style="background-color: #2F2F2F"> </span><span style="background-color: #2C2C2C"> </span><span style="background-color: #222222"> </span><span style="background-color: #282828"> </span><span style="background-color: #2D2D2D"> </span><span style="background-color: #3E3E3E"> </span><span style="background-color: #4D4D4D"> </span><span style="background-color: #616161"> </span><span style="background-color: #636363"> </span><span style="background-color: #666666"> </span><span style="background-color: #606060"> </span><span style="background-color: #535353"> </span><span style="background-color: #D4D4D4"> </span><span style="background-color: #E2E2E2"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #DCDCDC"> </span><span style="background-color: #AFAFAF"> </span><span style="background-color: #666666"> </span><span style="background-color: #6F6F6F"> </span><span style="background-color: #717171"> </span><span style="background-color: #242424"> </span><span style="background-color: #191919"> </span><span> </span>
<span style="background-color: #2C2C2C"> </span><span style="background-color: #343434"> </span><span style="background-color: #2E2E2E"> </span><span style="background-color: #262626"> </span><span style="background-color: #404040"> </span><span style="background-color: #868686"> </span><span style="background-color: #4D4D4D"> </span><span style="background-color: #5A5A5A"> </span><span style="background-color: #3D3D3D"> </span><span style="background-color: #474747"> </span><span style="background-color: #646464"> </span><span style="background-color: #616161"> </span><span style="background-color: #4D4D4D"> </span><span style="background-color: #9D9D9D"> </span><span style="background-color: #C8C8C8"> </span><span style="background-color: #DADADA"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #C4C4C4"> </span><span style="background-color: #717171"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #595959"> </span><span style="background-color: #343434"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #191919"> </span><span> </span>
<span style="background-color: #343434"> </span><span style="background-color: #575757"> </span><span style="background-color: #555555"> </span><span style="background-color: #454545"> </span><span style="background-color: #4C4C4C"> </span><span style="background-color: #656565"> </span><span style="background-color: #5B5B5B"> </span><span style="background-color: #434343"> </span><span style="background-color: #3E3E3E"> </span><span style="background-color: #595959"> </span><span style="background-color: #666666"> </span><span style="background-color: #606060"> </span><span style="background-color: #595959"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #787878"> </span><span style="background-color: #9E9E9E"> </span><span style="background-color: #797979"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #575757"> </span><span style="background-color: #343434"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #191919"> </span><span> </span>
<span style="background-color: #2B2B2B"> </span><span style="background-color: #3B3B3B"> </span><span style="background-color: #575757"> </span><span style="background-color: #646464"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #575757"> </span><span style="background-color: #3D3D3D"> </span><span style="background-color: #525252"> </span><span style="background-color: #656565"> </span><span style="background-color: #666666"> </span><span style="background-color: #656565"> </span><span style="background-color: #616161"> </span><span style="background-color: #595959"> </span><span style="background-color: #4B4B4B"> </span><span style="background-color: #454545"> </span><span style="background-color: #4B4B4B"> </span><span style="background-color: #555555"> </span><span style="background-color: #5D5D5D"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #575757"> </span><span style="background-color: #343434"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #191919"> </span><span> </span>
<span style="background-color: #3A3A3A"> </span><span style="background-color: #292929"> </span><span style="background-color: #323232"> </span><span style="background-color: #4A4A4A"> </span><span style="background-color: #626262"> </span><span style="background-color: #666666"> </span><span style="background-color: #656565"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #616161"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #616161"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #666666"> </span><span style="background-color: #626262"> </span><span style="background-color: #575757"> </span><span style="background-color: #4B4B4B"> </span><span style="background-color: #454545"> </span><span style="background-color: #4A4A4A"> </span><span style="background-color: #545454"> </span><span style="background-color: #343434"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #191919"> </span><span> </span>
<span> </span><span style="background-color: #252525"> </span><span style="background-color: #383838"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #616161"> </span><span style="background-color: #5B5B5B"> </span><span style="background-color: #505050"> </span><span style="background-color: #545454"> </span><span style="background-color: #8A8A8A"> </span><span style="background-color: #C5C5C5"> </span><span style="background-color: #959595"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #636363"> </span><span style="background-color: #666666"> </span><span style="background-color: #626262"> </span><span style="background-color: #595959"> </span><span style="background-color: #4D4D4D"> </span><span style="background-color: #454545"> </span><span style="background-color: #414141"> </span><span style="background-color: #282828"> </span><span style="background-color: #1E1E1E"> </span><span style="background-color: #1D1D1D"> </span><span> </span>
<span> </span><span style="background-color: #212121"> </span><span style="background-color: #2C2C2C"> </span><span style="background-color: #4F4F4F"> </span><span style="background-color: #515151"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #898989"> </span><span style="background-color: #CDCDCD"> </span><span style="background-color: #E8E8E8"> </span><span style="background-color: #DEDEDE"> </span><span style="background-color: #D8D8D8"> </span><span style="background-color: #939393"> </span><span style="background-color: #4D4D4D"> </span><span style="background-color: #525252"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #646464"> </span><span style="background-color: #666666"> </span><span style="background-color: #636363"> </span><span style="background-color: #5A5A5A"> </span><span style="background-color: #4A4A4A"> </span><span style="background-color: #383838"> </span><span style="background-color: #323232"> </span><span style="background-color: #2A2A2A"> </span><span style="background-color: #282828"> </span><span> </span>
<span> </span><span style="background-color: #272727"> </span><span style="background-color: #404040"> </span><span style="background-color: #C8C8C8"> </span><span style="background-color: #DFDFDF"> </span><span style="background-color: #F0F0F0"> </span><span style="background-color: #FDFDFD"> </span><span style="background-color: #F3F3F3"> </span><span style="background-color: #DFDFDF"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #D7D7D7"> </span><span style="background-color: #757575"> </span><span style="background-color: #2B2B2B"> </span><span style="background-color: #333333"> </span><span style="background-color: #444444"> </span><span style="background-color: #535353"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #646464"> </span><span style="background-color: #666666"> </span><span style="background-color: #646464"> </span><span style="background-color: #5B5B5B"> </span><span style="background-color: #4F4F4F"> </span><span style="background-color: #3A3A3A"> </span><span style="background-color: #292929"> </span>
<span> </span><span style="background-color: #242424"> </span><span style="background-color: #4F4F4F"> </span><span style="background-color: #E7E7E7"> </span><span style="background-color: #FFFFFF"> </span><span style="background-color: #F2F2F2"> </span><span style="background-color: #DFDFDF"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #C2C2C2"> </span><span style="background-color: #6E6E6E"> </span><span style="background-color: #434343"> </span><span style="background-color: #242424"> </span><span style="background-color: #222222"> </span><span style="background-color: #282828"> </span><span style="background-color: #343434"> </span><span style="background-color: #454545"> </span><span style="background-color: #555555"> </span><span style="background-color: #606060"> </span><span style="background-color: #656565"> </span><span style="background-color: #666666"> </span><span style="background-color: #595959"> </span><span style="background-color: #313131"> </span>
<span> </span><span style="background-color: #222222"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #F2F2F2"> </span><span style="background-color: #FFFFFF"> </span><span style="background-color: #F4F4F4"> </span><span style="background-color: #D7D7D7"> </span><span style="background-color: #DCDCDC"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #D1D1D1"> </span><span style="background-color: #818181"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5D5D5D"> </span><span style="background-color: #434343"> </span><span style="background-color: #242424"> </span><span style="background-color: #202020"> </span><span style="background-color: #222222"> </span><span style="background-color: #282828"> </span><span style="background-color: #353535"> </span><span style="background-color: #464646"> </span><span style="background-color: #565656"> </span><span style="background-color: #606060"> </span><span style="background-color: #656565"> </span><span style="background-color: #666666"> </span><span style="background-color: #585858"> </span><span style="background-color: #333333"> </span>
<span> </span><span style="background-color: #222222"> </span><span style="background-color: #707070"> </span><span style="background-color: #FAFAFA"> </span><span style="background-color: #D2D2D2"> </span><span style="background-color: #D9D9D9"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #D9D9D9"> </span><span style="background-color: #979797"> </span><span style="background-color: #616161"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5D5D5D"> </span><span style="background-color: #434343"> </span><span style="background-color: #242424"> </span><span style="background-color: #202020"> </span><span style="background-color: #222222"> </span><span style="background-color: #292929"> </span><span style="background-color: #363636"> </span><span style="background-color: #474747"> </span><span style="background-color: #575757"> </span><span style="background-color: #606060"> </span><span style="background-color: #616161"> </span><span style="background-color: #575757"> </span><span style="background-color: #404040"> </span><span style="background-color: #2B2B2B"> </span>
<span> </span><span style="background-color: #212121"> </span><span style="background-color: #858585"> </span><span style="background-color: #FCFCFC"> </span><span style="background-color: #D9D9D9"> </span><span style="background-color: #D2D2D2"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #DCDCDC"> </span><span style="background-color: #AEAEAE"> </span><span style="background-color: #666666"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5D5D5D"> </span><span style="background-color: #434343"> </span><span style="background-color: #242424"> </span><span style="background-color: #202020"> </span><span style="background-color: #222222"> </span><span style="background-color: #292929"> </span><span style="background-color: #363636"> </span><span style="background-color: #3E3E3E"> </span><span style="background-color: #363636"> </span><span style="background-color: #2B2B2B"> </span><span style="background-color: #282828"> </span>
<span> </span><span style="background-color: #222222"> </span><span style="background-color: #9B9B9B"> </span><span style="background-color: #EAEAEA"> </span><span style="background-color: #D0D0D0"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #C3C3C3"> </span><span style="background-color: #707070"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5D5D5D"> </span><span style="background-color: #434343"> </span><span style="background-color: #242424"> </span><span style="background-color: #202020"> </span><span style="background-color: #212121"> </span><span style="background-color: #242424"> </span><span style="background-color: #272727"> </span><span style="background-color: #2C2C2C"> </span><span> </span>
<span> </span><span style="background-color: #292929"> </span><span style="background-color: #ACACAC"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #DCDCDC"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #D1D1D1"> </span><span style="background-color: #818181"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5D5D5D"> </span><span style="background-color: #434343"> </span><span style="background-color: #242424"> </span><span style="background-color: #202020"> </span><span style="background-color: #212121"> </span><span style="background-color: #222222"> </span><span style="background-color: #232323"> </span><span style="background-color: #242424"> </span><span style="background-color: #262626"> </span><span style="background-color: #2E2E2E"> </span><span> </span>
<span> </span><span style="background-color: #2D2D2D"> </span><span style="background-color: #A6A6A6"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #D9D9D9"> </span><span style="background-color: #989898"> </span><span style="background-color: #616161"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5D5D5D"> </span><span style="background-color: #3E3E3E"> </span><span style="background-color: #222222"> </span><span style="background-color: #242424"> </span><span style="background-color: #262626"> </span><span style="background-color: #2B2B2B"> </span><span style="background-color: #363636"> </span><span> </span>
<span> </span><span style="background-color: #212121"> </span><span style="background-color: #575757"> </span><span style="background-color: #BEBEBE"> </span><span style="background-color: #DDDDDD"> </span><span style="background-color: #DCDCDC"> </span><span style="background-color: #AFAFAF"> </span><span style="background-color: #666666"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5B5B5B"> </span><span style="background-color: #373737"> </span><span style="background-color: #222222"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #212121"> </span><span style="background-color: #585858"> </span><span style="background-color: #BEBEBE"> </span><span style="background-color: #C3C3C3"> </span><span style="background-color: #717171"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #424242"> </span><span style="background-color: #252525"> </span><span style="background-color: #242424"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #212121"> </span><span style="background-color: #545454"> </span><span style="background-color: #717171"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #4D4D4D"> </span><span style="background-color: #292929"> </span><span style="background-color: #232323"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #343434"> </span><span style="background-color: #565656"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #565656"> </span><span style="background-color: #303030"> </span><span style="background-color: #222222"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #343434"> </span><span style="background-color: #565656"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5C5C5C"> </span><span style="background-color: #393939"> </span><span style="background-color: #232323"> </span><span style="background-color: #252525"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #343434"> </span><span style="background-color: #565656"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #5E5E5E"> </span><span style="background-color: #444444"> </span><span style="background-color: #252525"> </span><span style="background-color: #222222"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #343434"> </span><span style="background-color: #565656"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #4F4F4F"> </span><span style="background-color: #2A2A2A"> </span><span style="background-color: #222222"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #343434"> </span><span style="background-color: #565656"> </span><span style="background-color: #5F5F5F"> </span><span style="background-color: #575757"> </span><span style="background-color: #323232"> </span><span style="background-color: #222222"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #343434"> </span><span style="background-color: #565656"> </span><span style="background-color: #5C5C5C"> </span><span style="background-color: #3C3C3C"> </span><span style="background-color: #232323"> </span><span style="background-color: #252525"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1F1F1F"> </span><span style="background-color: #343434"> </span><span style="background-color: #404040"> </span><span style="background-color: #262626"> </span><span style="background-color: #232323"> </span><span> </span>
<span> </span><span style="background-color: #171717"> </span><span style="background-color: #1E1E1E"> </span><span style="background-color: #222222"> </span><span> </span>
</pre>

View File

@@ -0,0 +1,52 @@
Title: Canvas
Order: 60
---
`Canvas` is a widget that allows you to render arbitrary "pixels"
(or _coxels_, as [Simon Cropp](https://twitter.com/SimonCropp/status/1331554791726534657?s=20)
suggested we should call them).
# Drawing primitives
```csharp
// Create a canvas
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
AnsiConsole.Render(canvas);
```
## Result
<pre style="font-size:100%;font-family:consolas,'Courier New',monospace;line-height: normal; padding: 0px;background-color: #222222; padding: 20px;">
<span style="background-color: #008000"> </span><span style="background-color: #FF0000"> </span>
<span style="background-color: #008000"> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span style="background-color: #800080"> </span><span> </span><span style="background-color: #800080"> </span><span style="background-color: #FFFF00"> </span>
<span style="background-color: #008000"> </span><span style="background-color: #0000FF"> </span><span style="background-color: #FFFF00"> </span>
</pre>

View File

@@ -0,0 +1,34 @@
Title: Figlet
Order: 50
RedirectFrom: figlet
---
Spectre.Console can render [FIGlet](http://www.figlet.org/) text by using the `FigletText` class.
# Default font
```csharp
AnsiConsole.Render(
new FigletText("Hello")
.LeftAligned()
.Color(Color.Red));
```
```text
_ _ _ _
| | | | ___ | | | | ___
| |_| | / _ \ | | | | / _ \
| _ | | __/ | | | | | (_) |
|_| |_| \___| |_| |_| \___/
```
# Custom font
```csharp
var font = FigletFont.Load("starwars.flf");
AnsiConsole.Render(
new FigletText(font, "Hello")
.LeftAligned()
.Color(Color.Red));
```

View File

@@ -0,0 +1,12 @@
Title: Widgets
Order: 9
---
<h1>Sections</h1>
<ul>
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
{
<li>@Html.DocumentLink(child)</li>
}
</ul>

View File

@@ -0,0 +1,72 @@
Title: Rule
Order: 30
RedirectFrom: rule
---
The `Rule` class is used to render a horizontal rule (line) to the terminal.
<img src="../assets/images/rule.png" style="width: 100%;" />
# Usage
To render a rule without a title:
```csharp
var rule = new Rule();
AnsiConsole.Render(rule);
```
## Title
You can set the rule title markup text.
```csharp
var rule = new Rule("[red]Hello[/]");
AnsiConsole.Render(rule);
```
```text
───────────────────────────────── Hello ─────────────────────────────────
```
### Title alignment
You can set the rule's title alignment.
```csharp
var rule = new Rule("[red]Hello[/]");
rule.Alignment = Justify.Left;
AnsiConsole.Render(rule);
```
```text
── Hello ────────────────────────────────────────────────────────────────
```
You can also specify it via an extension method:
```csharp
var rule = new Rule("[red]Hello[/]");
rule.LeftAligned();
AnsiConsole.Render(rule);
```
```text
── Hello ────────────────────────────────────────────────────────────────
```
## Styling
```csharp
var rule = new Rule("[red]Hello[/]");
rule.Style = Style.Parse("red dim");
AnsiConsole.Render(rule);
```
You can also specify it via an extension method
```csharp
var rule = new Rule("[red]Hello[/]");
rule.RuleStyle("red dim");
AnsiConsole.Render(rule);
```

136
docs/input/widgets/table.md Normal file
View File

@@ -0,0 +1,136 @@
Title: Table
Order: 0
RedirectFrom: tables
---
Tables are a perfect way of displaying tabular data in a terminal.
`Spectre.Console` is super smart about rendering tables and will adjust
all columns to fit whatever is inside them. Anything that implements
`IRenderable` can be used as a column header or column cell, even another table!
# Usage
<!------------------------->
<!--- USAGE --->
<!------------------------->
To render a table, create a `Table` instance, add the number of
columns that you need, and then add the rows. Finish by passing the
table to a console's `Render` method.
```csharp
// Create a table
var table = new Table();
// Add some columns
table.AddColumn("Foo");
table.AddColumn(new TableColumn("Bar").Centered());
// Add some rows
table.AddRow("Baz", "[green]Qux[/]");
table.AddRow(new Markup("[blue]Corgi[/]"), new Panel("Waldo"));
// Render the table to the console
AnsiConsole.Render(table);
```
This will render the following output:
![Table](../assets/images/table.png)
# Table appearance
<!------------------------->
<!--- TABLE APPEARANCE --->
<!------------------------->
## Borders
For a list of borders, see the [Borders](xref:borders) appendix section.
```csharp
// Sets the border
table.Border(TableBorder.None);
table.Border(TableBorder.Ascii);
table.Border(TableBorder.Square);
table.Border(TableBorder.Rounded);
```
## Expand / Collapse
```csharp
// Table will take up as much space as it can
// with respect to other things.
table.Expand();
// Table will take up minimal width
table.Collapse();
```
## Hide headers
```csharp
// Hides all column headers
table.HideHeaders();
```
## Set table width
```csharp
// Sets the table width to 50 cells
table.Width(50);
```
## Alignment
```csharp
table.Alignment(Justify.Right);
table.RightAligned();
table.Centered();
table.LeftAligned();
```
# Column appearance
<!------------------------->
<!--- COLUMN APPEARANCE --->
<!------------------------->
## Alignment
```csharp
table.Columns[0].Alignment(Justify.Right);
table.Columns[0].LeftAligned();
table.Columns[0].Centered();
table.Columns[0].RightAligned();
```
## Padding
```csharp
// Set padding individually
table.Columns[0].PadLeft(3);
table.Columns[0].PadRight(5);
// Or chained together
table.Columns[0].PadLeft(3).PadRight(5);
// Or with the shorthand method if the left and right
// padding are identical. Vertical padding is ignored.
table.Columns[0].Padding(4, 0);
```
## Disable column wrapping
```csharp
// Disable column wrapping
table.Columns[0].NoWrap();
```
## Set column width
```csharp
// Set the column width
table.Columns[0].Width(15);
```

View File

@@ -0,0 +1,70 @@
Title: Tree
Order: 10
---
The `Tree` widget can be used to render hierarchical data.
<img src="../assets/images/tree.png" style="width: 100%;" />
# Usage
```csharp
// Create the tree
var root = new Tree("Root");
// Add some nodes
var foo = root.AddNode("[yellow]Foo[/]");
var table = foo.AddNode(new Table()
.RoundedBorder()
.AddColumn("First")
.AddColumn("Second")
.AddRow("1", "2")
.AddRow("3", "4")
.AddRow("5", "6"));
table.AddNode("[blue]Baz[/]");
foo.AddNode("Qux");
var bar = root.AddNode("[yellow]Bar[/]");
bar.AddNode(new Calendar(2020, 12)
.AddCalendarEvent(2020, 12, 12)
.HideHeader());
// Render the tree
AnsiConsole.Render(root);
```
# Collapsing nodes
```csharp
root.AddNode("Label").Collapsed();
```
# Appearance
## Style
```csharp
var root = new Tree("Root")
.Style("white on red");
```
## Guide lines
```csharp
// ASCII guide lines
var root = new Tree("Root")
.Guide(TreeGuide.Ascii);
// Default guide lines
var root = new Tree("Root")
.Guide(TreeGuide.Line);
// Double guide lines
var root = new Tree("Root")
.Guide(TreeGuide.DoubleLine);
// Bold guide lines
var root = new Tree("Root")
.Guide(TreeGuide.BoldLine);
```

View File

@@ -1,17 +1,23 @@
namespace Docs
namespace Docs
{
public static class Constants
{
public const string NoContainer = nameof(NoContainer);
public const string NoSidebar = nameof(NoSidebar);
public const string NoLink = nameof(NoLink);
public const string Topic = nameof(Topic);
public const string EditLink = nameof(EditLink);
public const string Description = nameof(Description);
public const string Hidden = nameof(Hidden);
public static class Emojis
{
public const string Root = "EMOJIS_ROOT";
}
public static class Colors
{
public const string Url = "https://raw.githubusercontent.com/spectresystems/spectre.console/main/resources/scripts/Generator/Data/colors.json";
public const string Url = "https://raw.githubusercontent.com/spectreconsole/spectre.console/main/resources/scripts/Generator/Data/colors.json";
public const string Root = "COLORS_ROOT";
}

7946
docs/src/Data/emojis.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -20,10 +20,7 @@ namespace Docs
public static Bootstrapper ConfigureDeployment(this Bootstrapper bootstrapper, string deployBranch)
{
if (bootstrapper != null)
{
bootstrapper.AddSetting(Constants.Deployment.TargetBranch, deployBranch);
}
bootstrapper?.AddSetting(Constants.Deployment.TargetBranch, deployBranch);
return bootstrapper;
}
}

View File

@@ -1,4 +1,4 @@
using Statiq.Common;
using Statiq.Common;
using System.Collections.Generic;
using System.Linq;
@@ -11,20 +11,16 @@ namespace Docs
return document?.GetString(Constants.Description, string.Empty) ?? string.Empty;
}
public static bool HasVisibleChildren(this IDocument document)
{
if (document != null)
{
return document.HasChildren() && document.GetChildren().Any(x => x.IsVisible());
}
return false;
}
public static bool IsVisible(this IDocument document)
{
return !document.GetBool(Constants.Hidden, false);
}
public static bool ShowLink(this IDocument document)
{
return !document.GetBool(Constants.NoLink, false);
}
public static IEnumerable<IDocument> OnlyVisible(this IEnumerable<IDocument> source)
{
return source.Where(x => x.IsVisible());

20
docs/src/Models/Emoji.cs Normal file
View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
namespace Docs.Models
{
public sealed class Emoji
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Code { get; set; }
public static List<Emoji> Parse(string json)
{
return JsonConvert.DeserializeObject<List<Emoji>>(json);
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Statiq.Common;
namespace Docs.Modules
{
public sealed class ReadEmbedded : Module
{
private readonly System.Reflection.Assembly _assembly;
private readonly string _resource;
public ReadEmbedded(System.Reflection.Assembly assembly, string resource)
{
_assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
_resource = resource ?? throw new ArgumentNullException(nameof(resource));
}
protected override Task<IEnumerable<IDocument>> ExecuteContextAsync(IExecutionContext context)
{
return Task.FromResult((IEnumerable<IDocument>)new[]
{
context.CreateDocument(ReadResource()),
});
}
private Stream ReadResource()
{
var resourceName = _resource.Replace("/", ".");
var stream = _assembly.GetManifestResourceStream(resourceName);
if (stream == null)
{
throw new InvalidOperationException("Could not load manifest resource stream.");
}
return stream;
}
}
}

View File

@@ -1,8 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Docs.Models;
using NJsonSchema;
using Statiq.Common;
using Statiq.Core;
@@ -10,15 +9,13 @@ namespace Docs.Pipelines
{
public class ColorsPipeline : Pipeline
{
public const string Url = "https://raw.githubusercontent.com/spectresystems/spectre.console/main/resources/scripts/Generator/Data/colors.json";
public ColorsPipeline()
{
InputModules = new ModuleList
{
new ExecuteConfig(
Config.FromContext(ctx => {
return new ReadWeb(Url);
return new ReadWeb(Constants.Colors.Url);
}))
};
@@ -27,15 +24,10 @@ namespace Docs.Pipelines
new ExecuteConfig(
Config.FromDocument(async (doc, ctx) =>
{
var colors = Color.Parse(await doc.GetContentStringAsync()).ToList();
var definitions = new List<IDocument> { colors.ToDocument(Constants.Colors.Root) };
return doc.Clone(new MetadataDictionary
{
[Constants.Colors.Root] = definitions
});
var data = Color.Parse(await doc.GetContentStringAsync()).ToList();
return data.ToDocument(Constants.Colors.Root);
}))
};
}
}
}
}

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using Docs.Models;
using Docs.Modules;
using Statiq.Common;
using Statiq.Core;
namespace Docs.Pipelines
{
public class EmojiPipeline : Pipeline
{
public EmojiPipeline()
{
InputModules = new ModuleList
{
new ExecuteConfig(
Config.FromContext(ctx => {
return new ReadEmbedded(
typeof(EmojiPipeline).Assembly,
"Docs/src/Data/emojis.json");
}))
};
ProcessModules = new ModuleList
{
new ExecuteConfig(
Config.FromDocument(async (doc, ctx) =>
{
var data = Emoji.Parse(await doc.GetContentStringAsync());
return data.ToDocument(Constants.Emojis.Root);
}))
};
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NJsonSchema;
using Statiq.Common;
using System.Xml.Linq;
using Docs.Pipelines;
@@ -18,14 +17,14 @@ namespace Docs.Shortcodes
// Get the definition.
var colors = context.Outputs
.FromPipeline(nameof(ColorsPipeline))
.First()
.GetChildren(Constants.Colors.Root)
.OfType<ObjectDocument<List<Color>>>()
.First().Object;
var table = new XElement("table", new XAttribute("class", "table"));
// Headers
var table = new XElement("table", new XAttribute("class", "table"), new XAttribute("id", "color-results"));
var header = new XElement("tr", new XAttribute("class", "color-row"));
header.Add(new XElement("th", ""));
header.Add(new XElement("th", "#"));
header.Add(new XElement("th", "Name"));
header.Add(new XElement("th", "RGB"));
header.Add(new XElement("th", "Hex"));
@@ -34,19 +33,21 @@ namespace Docs.Shortcodes
foreach (var color in colors)
{
var rep = new XElement("td",
new XElement("span",
var rep = new XElement("td",
new XElement("span",
new XAttribute("class", "color-representation"),
new XAttribute("style", $"background-color:{color.Hex};")));
var name = new XElement("td", new XElement("code", color.Name.ToLower()));
var name = new XElement("td", new XElement("code", color.Number.ToString()));
var number = new XElement("td", new XElement("code", color.Name.ToLower()));
var rgb = new XElement("td", new XElement("code", $"{color.R},{color.G},{color.B}"));
var hex = new XElement("td", new XElement("code", color.Hex));
var clr = new XElement("td", new XElement("code", color.ClrName));
// Create row
var row = new XElement("tr");
var row = new XElement("tr", new XAttribute("class", "search-row"));
row.Add(rep);
row.Add(name);
row.Add(number);
row.Add(rgb);
row.Add(hex);
row.Add(clr);

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Statiq.Common;
using System.Xml.Linq;
using Docs.Pipelines;
using Docs.Models;
namespace Docs.Shortcodes
{
public class EmojiTableShortcode : SyncShortcode
{
public override ShortcodeResult Execute(KeyValuePair<string, string>[] args, string content, IDocument document, IExecutionContext context)
{
var emojis = context.Outputs
.FromPipeline(nameof(EmojiPipeline))
.OfType<ObjectDocument<List<Emoji>>>()
.First().Object;
// Headers
var table = new XElement("table", new XAttribute("class", "table"), new XAttribute("id", "emoji-results"));
var header = new XElement("tr", new XAttribute("class", "emoji-row-header"));
header.Add(new XElement("th", ""));
header.Add(new XElement("th", "Markup"));
header.Add(new XElement("th", "Constant"));
table.Add(header);
foreach (var emoji in emojis)
{
var code = emoji.Code.Replace("U+0000", "U+").Replace("U+000", "U+");
var icon = $"&#x{emoji.Code.Replace("U+", string.Empty)};";
var row = new XElement("tr", new XAttribute("class", "search-row"));
row.Add(new XElement("td", icon));
row.Add(new XElement("td", new XElement("code", $":{emoji.Id}:")));
row.Add(new XElement("td", new XElement("code", emoji.Name)));
table.Add(row);
}
return table.ToString()
.Replace("&amp;#x", "&#x");
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace Docs.Utilities
{
public static class VersionUtilities
{
public static string GetVersion()
{
return GetVersion(typeof(VersionUtilities).Assembly);
}
private static string GetVersion(Assembly assembly)
{
if (assembly == null)
{
return "?";
}
try
{
var info = FileVersionInfo.GetVersionInfo(assembly.Location);
return info.ProductVersion ?? "?";
}
catch
{
return "?";
}
}
}
}

View File

@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"cake.tool": {
"version": "0.38.4",
"version": "1.1.0",
"commands": [
"dotnet-cake"
]
@@ -13,6 +13,12 @@
"commands": [
"gpr"
]
},
"dotnet-example": {
"version": "1.2.0",
"commands": [
"dotnet-example"
]
}
}
}

View File

@@ -0,0 +1,16 @@
using System.ComponentModel;
using Spectre.Console.Cli;
namespace Spectre.Console.Examples
{
public static partial class Program
{
public sealed class BarSettings : CommandSettings
{
[CommandOption("--count")]
[Description("The number of bars to print")]
[DefaultValue(1)]
public int Count { get; set; }
}
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
<ExampleName>Delegates</ExampleName>
<ExampleDescription>Demonstrates how to specify commands as delegates.</ExampleDescription>
<ExampleGroup>Cli</ExampleGroup>
<ExampleVisible>false</ExampleVisible>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,38 @@
using Spectre.Console.Cli;
namespace Spectre.Console.Examples
{
public static partial class Program
{
public static int Main(string[] args)
{
var app = new CommandApp();
app.Configure(config =>
{
config.AddDelegate("foo", Foo)
.WithDescription("Foos the bars");
config.AddDelegate<BarSettings>("bar", Bar)
.WithDescription("Bars the foos"); ;
});
return app.Run(args);
}
private static int Foo(CommandContext context)
{
AnsiConsole.WriteLine("Foo");
return 0;
}
private static int Bar(CommandContext context, BarSettings settings)
{
for (var index = 0; index < settings.Count; index++)
{
AnsiConsole.WriteLine("Bar");
}
return 0;
}
}
}

View File

@@ -0,0 +1,47 @@
using System.ComponentModel;
using Demo.Utilities;
using Spectre.Console.Cli;
namespace Demo.Commands
{
[Description("Add a NuGet package reference to the project.")]
public sealed class AddPackageCommand : Command<AddPackageCommand.Settings>
{
public sealed class Settings : AddSettings
{
[CommandArgument(0, "<PACKAGENAME>")]
[Description("The package reference to add.")]
public string PackageName { get; set; }
[CommandOption("-v|--version <VERSION>")]
[Description("The version of the package to add.")]
public string Version { get; set; }
[CommandOption("-f|--framework <FRAMEWORK>")]
[Description("Add the reference only when targeting a specific framework.")]
public string Framework { get; set; }
[CommandOption("--no-restore")]
[Description("Add the reference without performing restore preview and compatibility check.")]
public bool NoRestore { get; set; }
[CommandOption("--source <SOURCE>")]
[Description("The NuGet package source to use during the restore.")]
public string Source { get; set; }
[CommandOption("--package-directory <PACKAGEDIR>")]
[Description("The directory to restore packages to.")]
public string PackageDirectory { get; set; }
[CommandOption("--interactive")]
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
public bool Interactive { get; set; }
}
public override int Execute(CommandContext context, Settings settings)
{
SettingsDumper.Dump(settings);
return 0;
}
}
}

View File

@@ -0,0 +1,30 @@
using System.ComponentModel;
using Demo.Utilities;
using Spectre.Console.Cli;
namespace Demo.Commands
{
public sealed class AddReferenceCommand : Command<AddReferenceCommand.Settings>
{
public sealed class Settings : AddSettings
{
[CommandArgument(0, "<PROJECTPATH>")]
[Description("The package reference to add.")]
public string ProjectPath { get; set; }
[CommandOption("-f|--framework <FRAMEWORK>")]
[Description("Add the reference only when targeting a specific framework.")]
public string Framework { get; set; }
[CommandOption("--interactive")]
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
public bool Interactive { get; set; }
}
public override int Execute(CommandContext context, Settings settings)
{
SettingsDumper.Dump(settings);
return 0;
}
}
}

View File

@@ -0,0 +1,12 @@
using System.ComponentModel;
using Spectre.Console.Cli;
namespace Demo.Commands
{
public abstract class AddSettings : CommandSettings
{
[CommandArgument(0, "<PROJECT>")]
[Description("The project file to operate on. If a file is not specified, the command will search the current directory for one.")]
public string Project { get; set; }
}
}

View File

@@ -0,0 +1,70 @@
using System.ComponentModel;
using Demo.Utilities;
using Spectre.Console.Cli;
namespace Demo.Commands
{
[Description("Build and run a .NET project output.")]
public sealed class RunCommand : Command<RunCommand.Settings>
{
public sealed class Settings : CommandSettings
{
[CommandOption("-c|--configuration <CONFIGURATION>")]
[Description("The configuration to run for. The default for most projects is '[grey]Debug[/]'.")]
[DefaultValue("Debug")]
public string Configuration { get; set; }
[CommandOption("-f|--framework <FRAMEWORK>")]
[Description("The target framework to run for. The target framework must also be specified in the project file.")]
public string Framework { get; set; }
[CommandOption("-r|--runtime <RUNTIMEIDENTIFIER>")]
[Description("The target runtime to run for.")]
public string RuntimeIdentifier { get; set; }
[CommandOption("-p|--project <PROJECTPATH>")]
[Description("The path to the project file to run (defaults to the current directory if there is only one project).")]
public string ProjectPath { get; set; }
[CommandOption("--launch-profile <LAUNCHPROFILE>")]
[Description("The name of the launch profile (if any) to use when launching the application.")]
public string LaunchProfile { get; set; }
[CommandOption("--no-launch-profile")]
[Description("Do not attempt to use [grey]launchSettings.json[/] to configure the application.")]
public bool NoLaunchProfile { get; set; }
[CommandOption("--no-build")]
[Description("Do not build the project before running. Implies [grey]--no-restore[/].")]
public bool NoBuild { get; set; }
[CommandOption("--interactive")]
[Description("Allows the command to stop and wait for user input or action (for example to complete authentication).")]
public string Interactive { get; set; }
[CommandOption("--no-restore")]
[Description("Do not restore the project before building.")]
public bool NoRestore { get; set; }
[CommandOption("--verbosity <VERBOSITY>")]
[Description("Set the MSBuild verbosity level. Allowed values are q[grey]uiet[/], m[grey]inimal[/], n[grey]ormal[/], d[grey]etailed[/], and diag[grey]nostic[/].")]
[TypeConverter(typeof(VerbosityConverter))]
[DefaultValue(Verbosity.Normal)]
public Verbosity Verbosity { get; set; }
[CommandOption("--no-dependencies")]
[Description("Do not restore project-to-project references and only restore the specified project.")]
public bool NoDependencies { get; set; }
[CommandOption("--force")]
[Description("Force all dependencies to be resolved even if the last restore was successful. This is equivalent to deleting [grey]project.assets.json[/].")]
public bool Force { get; set; }
}
public override int Execute(CommandContext context, Settings settings)
{
SettingsDumper.Dump(settings);
return 0;
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.ComponentModel;
using Demo.Utilities;
using Spectre.Console.Cli;
namespace Demo.Commands
{
[Description("Launches a web server in the current working directory and serves all files in it.")]
public sealed class ServeCommand : Command<ServeCommand.Settings>
{
public sealed class Settings : CommandSettings
{
[CommandOption("-p|--port <PORT>")]
[Description("Port to use. Defaults to [grey]8080[/]. Use [grey]0[/] for a dynamic port.")]
public int Port { get; set; }
[CommandOption("-o|--open-browser [BROWSER]")]
[Description("Open a web browser when the server starts. You can also specify which browser to use. If none is specified, the default one will be used.")]
public FlagValue<string> OpenBrowser { get; set; }
}
public override int Execute(CommandContext context, Settings settings)
{
if (settings.OpenBrowser.IsSet)
{
var browser = settings.OpenBrowser.Value;
if (browser != null)
{
Console.WriteLine($"Open in {browser}");
}
else
{
Console.WriteLine($"Open in default browser.");
}
}
SettingsDumper.Dump(settings);
return 0;
}
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
<ExampleName>Demo</ExampleName>
<ExampleDescription>Demonstrates the most common use cases of Spectre.Cli.</ExampleDescription>
<ExampleGroup>Cli</ExampleGroup>
<ExampleVisible>false</ExampleVisible>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,37 @@
using Demo.Commands;
using Spectre.Console.Cli;
namespace Demo
{
public static class Program
{
public static int Main(string[] args)
{
var app = new CommandApp();
app.Configure(config =>
{
config.SetApplicationName("fake-dotnet");
config.ValidateExamples();
config.AddExample(new[] { "run", "--no-build" });
// Run
config.AddCommand<RunCommand>("run");
// Add
config.AddBranch<AddSettings>("add", add =>
{
add.SetDescription("Add a package or reference to a .NET project");
add.AddCommand<AddPackageCommand>("package");
add.AddCommand<AddReferenceCommand>("reference");
});
// Serve
config.AddCommand<ServeCommand>("serve")
.WithExample(new[] { "serve", "-o", "firefox" })
.WithExample(new[] { "serve", "--port", "80", "-o", "firefox" });
});
return app.Run(args);
}
}
}

View File

@@ -0,0 +1,29 @@
using Spectre.Console;
using Spectre.Console.Cli;
namespace Demo.Utilities
{
public static class SettingsDumper
{
public static void Dump(CommandSettings settings)
{
var table = new Table().RoundedBorder();
table.AddColumn("[grey]Name[/]");
table.AddColumn("[grey]Value[/]");
var properties = settings.GetType().GetProperties();
foreach (var property in properties)
{
var value = property.GetValue(settings)
?.ToString()
?.Replace("[", "[[");
table.AddRow(
property.Name,
value ?? "[grey]null[/]");
}
AnsiConsole.Render(table);
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
namespace Demo
{
public enum Verbosity
{
Quiet,
Minimal,
Normal,
Detailed,
Diagnostic
}
public sealed class VerbosityConverter : TypeConverter
{
private readonly Dictionary<string, Verbosity> _lookup;
public VerbosityConverter()
{
_lookup = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase)
{
{ "q", Verbosity.Quiet },
{ "quiet", Verbosity.Quiet },
{ "m", Verbosity.Minimal },
{ "minimal", Verbosity.Minimal },
{ "n", Verbosity.Normal },
{ "normal", Verbosity.Normal },
{ "d", Verbosity.Detailed },
{ "detailed", Verbosity.Detailed },
{ "diag", Verbosity.Diagnostic },
{ "diagnostic", Verbosity.Diagnostic }
};
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string stringValue)
{
var result = _lookup.TryGetValue(stringValue, out var verbosity);
if (!result)
{
const string format = "The value '{0}' is not a valid verbosity.";
var message = string.Format(CultureInfo.InvariantCulture, format, value);
throw new InvalidOperationException(message);
}
return verbosity;
}
throw new NotSupportedException("Can't convert value to verbosity.");
}
}
}

View File

@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
<ExampleName>Dynamic</ExampleName>
<ExampleDescription>Demonstrates how to define dynamic commands.</ExampleDescription>
<ExampleGroup>Cli</ExampleGroup>
<ExampleVisible>false</ExampleVisible>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Shared\Shared.csproj" />
</ItemGroup>
</Project>

Some files were not shown because too many files have changed in this diff Show More