EluciusFTW.SpectreCoff
0.47.50
See the version list below for details.
dotnet add package EluciusFTW.SpectreCoff --version 0.47.50
NuGet\Install-Package EluciusFTW.SpectreCoff -Version 0.47.50
<PackageReference Include="EluciusFTW.SpectreCoff" Version="0.47.50" />
paket add EluciusFTW.SpectreCoff --version 0.47.50
#r "nuget: EluciusFTW.SpectreCoff, 0.47.50"
// Install EluciusFTW.SpectreCoff as a Cake Addin #addin nuget:?package=EluciusFTW.SpectreCoff&version=0.47.50 // Install EluciusFTW.SpectreCoff as a Cake Tool #tool nuget:?package=EluciusFTW.SpectreCoff&version=0.47.50
SpectreCoff
Spectre Console for F# - A thin, opinionated wrapper around Spectre.Console.
Available at Nuget: EluciusFTW.SpectreCoff.
Table of Contents
- Goals and Philosophy
- SpectreCoff Package
- SpectreCoff Cli
- Related Work
- License
- Feedback and Contributing
Goals and Philosophy
Before we get into the details, we'd like to outline our goals and our guiding principles for designing the SpectreCoff api surface.
Make Spectre.Console available for console applications in F# in an idiomatic way.
We expose separate functionality in different modules, as functions, with typed arguments instead of generics resp. object-typing. Since many of Spectre's functions can handle multiple different kinds of content that often means wrapping your content in discriminated union type. We believe that the expression of intent as well as the resulting robustness and clarity far outweigh the 'overhead' of wrapping.
Provide a simple and consistent api surface.
In SpectreCoff, we follow the structure Spectre.Console provides very closely.
- Features of Spectre are translated into modules of the same name.
- Whenever possible, each module exposes a function producing 'the module thing' that is of same name as the module. This will be in form of an
OutputPayload
. - The special module
Output
(which also defines the typeOutputPayload
), provides the functiontoConsole
with which everything can be printed.
In the example of the figlet widget of Spectre, which translates into the figlet module, it looks like this:
"Hello World" // figlet content |> figlet // main function of the module producing the figlet instance as a Renderable case of OutputPayload |> toConsole // toConsole function of the figlet module
Of course, for more complex objects, there will be more parameters needed. To achieve this simplicity, the main function uses some defaults (in this example the alignment of the figlet). These defaults can be overwritten 'globally' (as they are just static variables in the module), or passed to other functions taking in more arguments, e.g.,
"Hello again" |> alignedFiglet Left |> toConsole // if all your figlets should be left-aligned, you can also set that as the default and use the main figlet function defaultAlignment <- Left
Add a bit of sprinke on top.
Spectre is great in providing ways to customize output. We wanted to add a bit on top to make it easier to utilize custom styles consistently throughout applications. Among other things, we decided to include three different semantic levels of output, namely:
calm
,pumped
andedgy
, which we also call convenience styles. These are supported throughout the modules, and each style can be customized individually.Bake the cake and eat it, too.
We want to feel the joy, and pain, of using our api in the fullest. That's why we have included a cli project in this repository, where we expose the full documentation as well as provide examples for each functionality, using the api itself.
dotnet run figlet doc // prints the documentation of the figlet module dotnet run figlet example // shows examples of the module in action
SpectreCoff Package
SpectreCoff is organized in modules which mirror the features of Spectre.Console.
The source code for the nuget package can be found in the subfolder /src/spectrecoff/
.
Output and Markup
Spectre offers very flexible markup by using variations of this command (see here):
AnsiConsole.Markup("[red bold]{0}[/]", Markup.Escape("Hello [World]"));
There are several ways to achieve the same in SpectreCoff. The most direct translation looks like this:
markup (Some Color.Red) (Some Bold) "Hello [World]" |> printMarkedUpInline
However, we recommend using the dedicated OutputPayload
type, together with the toConsole
function, which will yield a consistent approach across all kinds of payloads. Using the suitable payload, the example above would look as follows,
MarkupCS (Color.Red, Bold, "Hello [World]") |> toConsole
Payloads
The following table lists all payloads currently available:
Type | Alias | Description | Parameters | Configurbility |
---|---|---|---|---|
MarkupD |
MD |
Content marked up with decorations | decorations: Spectre.Console.Decoration list <br /> content: string |
- |
MarkupC |
MC |
Content marked up with a color | color: Spectre.Console.Color <br /> content: string |
- |
MarkupCD |
MCD |
Content marked up with a color and decorations | decorations: Spectre.Console.Decoration list <br /> color: Spectre.Console.Color <br /> content: string |
- |
Calm |
C |
Convenience style for calm output | content: string |
color: Output.calmLook.Color <br /> decorations: Output.calmLook.Decorations |
Pumped |
P |
Convenience style pumped output | content: string |
color: Output.pumpedLook.Color <br /> decorations: Output.pumpedLook.Decorations |
Edgy |
E |
Convenience style for edgy output | content: string |
color: Output.edgyLook.Color <br /> decorations: Output.edgyLook.Decorations |
Vanilla |
V |
Raw type, no processing will be done | content: string |
- |
NextLine |
NL |
Ends the current line | - | - |
BlankLine |
BL |
Ends the current line and adds an empty line | - | - |
Link |
- | Clickable link showing the URL | content: string |
color: Output.linkLook.Color <br /> decorations: Output.linkLook.Decorations |
LinkWithLabel |
- | Clickable link showing a label | label: string <br /> link: string |
color: Output.linkLook.Color <br /> decorations: Output.linkLook.Decorations |
Emoji |
- | An emoji, given by it's string literal | emoji: string |
- |
BulletItems |
BI |
Show list of items with bullet points | items: list of OutputPayload . <br /> Not allowed: Renderable , BulletItems |
bullet item prefix: Output.bulletItemPrefix |
Many |
- | Prints many payloads at once on the same line | items: list of OutputPayload |
- |
Renderable |
- | Wraps a Spectre.Rendering.IRenderable | content: Spectre.Rendering.IRenderable |
- |
Convenience Styles
The table above lists three convenience styles: Calm
, Pumped
and Edgy
. With these, we can easily provide a consistent, and semantically meaningful, styling across the modules:
Pumped "Hello world" |> toConsole
The convenience styles can be altered by mutating the corresponding variables, e.g.,
pumpedLook <- { Color = Color.Yellow; Decorations = [ Decoration.Italic ] }
Composition of Payloads
Some of the payloads listed above in turn accept payloads as arguments. Composing them in this way allows printing more complex content, as well as aggregating all output in one go before printing it. This can be seen in this example,
Many [
MarkupC (Color.Green, "Hello friends,") // Use any available color
BlankLine
Pumped "Welcome to my party tomorrow night!" // Use the Pumped convenience style
BL // short for BlankLine
C "Please bring ... " // short for Calm
BI [ // short for BulletItems
C "some snacks,"
P "some games," // short for Pumped
E "and some creepy stories!" // short for Edgy
]
C "See you "; P "later ... "; NL
Emoji "alien_monster"
] |> toConsole
In fact, any other payload can be composed using Many
(including others of type Many
, they will be flattened) and will be printed once toConsole
is called.
These composites are also the motivation for the short aliases of payloads, as these make it possible to focuis on the content and not be distracted too much by the types. For more examples, please see the sample command.
Note: Several features of Spectre.Console depend on UTF8 Encoding. If you experience unexpected output when handling UTF8 characters check the Spectre.Console best practices.
Deviations from Spectre
The Spectre widget Rows does not have it's own module as the Many
case of OutputPayload
covers the same functionality.
Versioning
We are using NerdBank.GitVersioning and follow the version scheme: <major>.<minor>.<git-depth>
for out releases.
Since this package is a wrapper around Spectre.Console, we will synchronize our major and minor versions with the ones of the Spectre dependency we are wrapping.
<b>Note</b>: In particular, the third number in the version does not have the same meaning as the patches in SemVer. Increments in that number may contain breaking changes, in contrast to patch versions in SemVer.
SpectreCoff Cli
You can see each module in action by using the cli included in this repository in /src/spectrecoff-cli/
.
Simply run
dotnet run <command> example | doc
for any command with the subcommand example
or doc
, depending on if you want to see an example, or the documentation of the command.
The currently supported commands are:
command | example | doc |
---|---|---|
output | ✅ | ❌ |
rule | ✅ | ✅ |
figlet | ✅ | ✅ |
panel | ✅ | ✅ |
prompt | ✅ | ✅ |
bar | ✅ | ✅ |
breakdown | ✅ | ✅ |
table | ✅ | ✅ |
tree | ✅ | ❌ |
calendar | ✅ | ❌ |
padder | ✅ | ✅ |
grid | ✅ | ✅ |
textpath | ✅ | ✅ |
json | ✅ | ✅ |
canvasimage | ✅ | ✅ |
canvas | ✅ | ❌ |
layout | ✅ | ❌ |
progress | ✅ | ❌ |
Related Work
In SpectreCoff we take the approach of providing types and functions wrapping the Spectre.Console api. If you prefer dsls via computation expressions, check out this awesome project (hey, even if you don't, check it out anyway!):
- fs-spectre - 👻💻 Spectre.Console with F# style.
Also, if you want to create a cli using Spectre.Console.Cli
(recently the cli part was extracted into a separate package), you can use my starter template:
- fsharp-spectre-console-template - A minimal starter template for using Spectre.Console.Cli in fsharp
License
Copyright © Guy Buss, Daniel Muckelbauer
SpectreCoff is provided as-is under the MIT license. See the LICENSE.md file included in the repository.
Feedback and Contributing
All feedback welcome! All contributions are welcome!
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- FSharp.Core (>= 6.0.0)
- Spectre.Console (>= 0.47.0)
- Spectre.Console.ImageSharp (>= 0.47.0)
- Spectre.Console.Json (>= 0.47.0)
-
net6.0
- FSharp.Core (>= 6.0.0)
- Spectre.Console (>= 0.47.0)
- Spectre.Console.ImageSharp (>= 0.47.0)
- Spectre.Console.Json (>= 0.47.0)
-
net7.0
- FSharp.Core (>= 6.0.0)
- Spectre.Console (>= 0.47.0)
- Spectre.Console.ImageSharp (>= 0.47.0)
- Spectre.Console.Json (>= 0.47.0)
Version | Downloads | Last updated |
---|---|---|
0.49.4 | 60 | 11/17/2024 |
0.49.2 | 574 | 5/3/2024 |
0.48.59 | 155 | 2/29/2024 |
0.48.56 | 120 | 2/29/2024 |
0.48.49 | 189 | 1/11/2024 |
0.48.24 | 142 | 1/8/2024 |
0.48.20 | 176 | 1/4/2024 |
0.48.18 | 148 | 12/21/2023 |
0.48.9 | 149 | 12/17/2023 |
0.48.1 | 195 | 11/26/2023 |
0.47.54 | 197 | 11/15/2023 |
0.47.51 | 145 | 11/9/2023 |
0.47.50 | 181 | 11/4/2023 |
0.47.47 | 164 | 11/4/2023 |
0.47.42 | 158 | 10/18/2023 |
0.47.39 | 164 | 9/25/2023 |
0.47.36 | 163 | 9/19/2023 |
0.47.33 | 155 | 9/16/2023 |
0.47.32 | 166 | 9/12/2023 |
0.47.28 | 15,746 | 9/9/2023 |
0.47.24 | 186 | 9/4/2023 |
0.47.23 | 206 | 8/28/2023 |
0.47.22 | 162 | 8/22/2023 |
0.47.17 | 184 | 8/12/2023 |
0.47.13 | 184 | 7/30/2023 |
0.47.7 | 201 | 7/28/2023 |
0.47.3 | 203 | 7/22/2023 |
0.47.1 | 185 | 7/9/2023 |
0.46.61 | 179 | 6/20/2023 |
0.46.51 | 211 | 5/24/2023 |
0.46.41 | 317 | 2/27/2023 |
0.46.35 | 272 | 2/21/2023 |
0.46.26 | 295 | 2/19/2023 |
0.46.19 | 306 | 2/13/2023 |
0.46.11 | 340 | 2/7/2023 |
0.46.4 | 351 | 1/27/2023 |
0.45.62 | 341 | 1/26/2023 |
0.45.56 | 339 | 1/14/2023 |
0.45.49 | 325 | 12/26/2022 |
0.45.48 | 363 | 12/25/2022 |
0.45.46 | 343 | 12/25/2022 |
0.45.45 | 356 | 12/24/2022 |
0.45.40 | 342 | 12/19/2022 |
0.45.36 | 353 | 12/19/2022 |
0.45.32 | 370 | 12/10/2022 |
0.45.31 | 329 | 12/6/2022 |
0.45.29 | 389 | 12/4/2022 |
0.45.28 | 391 | 12/1/2022 |
0.45.26 | 383 | 11/30/2022 |
0.45.25 | 363 | 11/27/2022 |
0.45.24 | 391 | 11/27/2022 |
0.45.20 | 351 | 11/24/2022 |
0.45.14 | 364 | 11/22/2022 |
0.45.9 | 414 | 11/12/2022 |
0.45.7 | 397 | 11/9/2022 |
0.45.6-pre | 213 | 11/9/2022 |
Added theming