Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d70ad661fc | ||
|
|
0d209d8f18 | ||
|
|
380c6aca45 | ||
|
|
b1da5e7ba8 | ||
|
|
be3350a411 | ||
|
|
a1d11e9d0c | ||
|
|
93d1971f48 | ||
|
|
bca1c889d1 | ||
|
|
9915a0d6a8 | ||
|
|
f34fc43d00 | ||
|
|
e7f497050c | ||
|
|
3e5e22d6c2 | ||
|
|
10daf727e9 | ||
|
|
03334f693d | ||
|
|
c9c0ad733f | ||
|
|
041bd016a2 | ||
|
|
037a215a78 | ||
|
|
9afc1ea721 | ||
|
|
b52056ee49 | ||
|
|
3941fd81ab | ||
|
|
5a1b8a1710 | ||
|
|
1410cba6c5 | ||
|
|
70fc14e9cd | ||
|
|
0b4359a52a | ||
|
|
cb2924a609 | ||
|
|
5c119ee0c3 | ||
|
|
b9d182b6e3 | ||
|
|
bfffef630f | ||
|
|
a2f507e58f | ||
|
|
d1d06d6a6b | ||
|
|
52718c499c | ||
|
|
7ef1ac483a | ||
|
|
c0875c912a | ||
|
|
3f2ca49071 | ||
|
|
0a0380ae0a | ||
|
|
ae92c606bb | ||
|
|
68e92f3365 | ||
|
|
39a8588dc3 | ||
|
|
3c3afe7439 | ||
|
|
971f9032ba | ||
|
|
5149557560 | ||
|
|
e0947708c9 | ||
|
|
b1db8a9403 | ||
|
|
a2f8652575 | ||
|
|
672faa131f | ||
|
|
e429f6434b | ||
|
|
93ec7401c8 | ||
|
|
697273917e | ||
|
|
2943535973 | ||
|
|
cd0d182f12 | ||
|
|
b197f278ed | ||
|
|
3847a8949f | ||
|
|
eeb3f967b6 | ||
|
|
090b30f731 | ||
|
|
df291ef84e | ||
|
|
7d6104ace4 | ||
|
|
314456ca17 | ||
|
|
b7f654cd7f | ||
|
|
fea8a36e8a | ||
|
|
0632b38477 | ||
|
|
a7b7d4e556 | ||
|
|
11d331e31d | ||
|
|
ce670a7ca9 | ||
|
|
101e244059 | ||
|
|
504746c5dc | ||
|
|
1601ef24b3 | ||
|
|
b46d0fa4f6 | ||
|
|
4f06687104 | ||
|
|
003e15686f | ||
|
|
3e9796849b | ||
|
|
3cc19520b0 | ||
|
|
87bde3e5a2 |
22
.github/workflows/ci.yaml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.301' # SDK Version to use.
|
dotnet-version: 5.0.100
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -55,20 +55,28 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet 3.1.402
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
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.100
|
||||||
|
|
||||||
- name: Integration Tests
|
- name: Integration Tests
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
dotnet tool restore
|
dotnet tool restore
|
||||||
dotnet example diagnostic
|
dotnet example info
|
||||||
dotnet example table
|
dotnet example tables
|
||||||
dotnet example grid
|
dotnet example grids
|
||||||
dotnet example panel
|
dotnet example panels
|
||||||
dotnet example colors
|
dotnet example colors
|
||||||
|
dotnet example emojis
|
||||||
|
dotnet example exceptions
|
||||||
|
dotnet example calendars
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
2
.github/workflows/docs.yaml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.301' # SDK Version to use.
|
dotnet-version: 5.0.100
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
20
.github/workflows/publish.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.301' # SDK Version to use.
|
dotnet-version: 5.0.100
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -64,10 +64,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet 3.1.402
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
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.100
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -90,10 +95,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet 3.1.402
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
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.100
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
2
.gitignore
vendored
@@ -5,6 +5,8 @@
|
|||||||
[Pp]ackages/
|
[Pp]ackages/
|
||||||
/.artifacts/
|
/.artifacts/
|
||||||
/[Tt]ools/
|
/[Tt]ools/
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
# Cakeup
|
# Cakeup
|
||||||
cakeup-x86_64-latest.exe
|
cakeup-x86_64-latest.exe
|
||||||
|
|||||||
413
README.jp.md
Normal file
@@ -0,0 +1,413 @@
|
|||||||
|
# `Spectre.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ビットカラーに対応しています。
|
||||||
|
ライブラリは現在のターミナルの性能を検知し、必要なカラーにダウングレードします
|
||||||
|
|
||||||
|
## 例
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
`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. │
|
||||||
|
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
|
||||||
|
```
|
||||||
|
|
||||||
|
そして、例を実行します
|
||||||
|
|
||||||
|
```
|
||||||
|
> 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);
|
||||||
|
```
|
||||||
|
|
||||||
|
これは次のように出力を描画します。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 罫線
|
||||||
|
|
||||||
|
|
||||||
|
```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);
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
### 例外の省略表示
|
||||||
|
|
||||||
|
例外の特定部分を短くして、さらに読みやすくしたり、パスをクリック可能なハイパーリンクにすることもできます。
|
||||||
|
ハイパーリンクがクリックできるかはターミナル次第です。
|
||||||
|
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
AnsiConsole.WriteException(ex,
|
||||||
|
ExceptionFormats.ShortenPaths | ExceptionFormats.ShortenTypes |
|
||||||
|
ExceptionFormats.ShortenMethods | ExceptionFormats.ShowLinks);
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 例外出力のカスタマイズ
|
||||||
|
|
||||||
|
例外の特定部分を短縮するだけでなく、デフォルトのスタイルを上書きすることもできます。
|
||||||
|
|
||||||
|
```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),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
47
README.md
@@ -10,10 +10,11 @@ for Python.
|
|||||||
|
|
||||||
1. [Features](#features)
|
1. [Features](#features)
|
||||||
2. [Example](#example)
|
2. [Example](#example)
|
||||||
3. [Usage](#usage)
|
3. [Installing](#installing)
|
||||||
3.1. [Using the static API](#using-the-static-api)
|
4. [Usage](#usage)
|
||||||
3.2. [Creating a console](#creating-a-console)
|
4.1. [Using the static API](#using-the-static-api)
|
||||||
4. [Running examples](#running-examples)
|
4.2. [Creating a console](#creating-a-console)
|
||||||
|
5. [Running examples](#running-examples)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -30,6 +31,14 @@ for Python.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
The fastest way of getting started using Spectre.Console is to install the NuGet package.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
dotnet add package Spectre.Console
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The `Spectre.Console` API is stateful and is not thread-safe.
|
The `Spectre.Console` API is stateful and is not thread-safe.
|
||||||
@@ -40,7 +49,7 @@ regular `System.Console` API.
|
|||||||
If the current terminal does not support ANSI escape sequences,
|
If the current terminal does not support ANSI escape sequences,
|
||||||
`Spectre.Console` will fallback to using the `System.Console` API.
|
`Spectre.Console` will fallback to using the `System.Console` API.
|
||||||
|
|
||||||
_NOTE: This library is currently under development and API's
|
_NOTE: This library is currently under development and APIs
|
||||||
might change or get removed at any point up until a 1.0 release._
|
might change or get removed at any point up until a 1.0 release._
|
||||||
|
|
||||||
### Using the static API
|
### Using the static API
|
||||||
@@ -91,7 +100,7 @@ To see Spectre.Console in action, install the
|
|||||||
global tool.
|
global tool.
|
||||||
|
|
||||||
```
|
```
|
||||||
> dotnet tool install -g dotnet-example
|
> dotnet tool restore
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you can list available examples in this repository:
|
Now you can list available examples in this repository:
|
||||||
@@ -99,20 +108,28 @@ Now you can list available examples in this repository:
|
|||||||
```
|
```
|
||||||
> dotnet example
|
> dotnet example
|
||||||
|
|
||||||
╭────────┬───────────────────────────────┬─────────────────────────────────────────────────╮
|
╭────────────┬───────────────────────────────────────┬──────────────────────────────────────────────────────╮
|
||||||
│ Name │ Path │ Description │
|
│ Name │ Path │ Description │
|
||||||
├────────┼───────────────────────────────┼─────────────────────────────────────────────────┤
|
├────────────┼───────────────────────────────────────┼──────────────────────────────────────────────────────┤
|
||||||
│ Colors │ examples/Colors/Colors.csproj │ Demonstrates how to use colors in the console. │
|
│ Borders │ examples/Borders/Borders.csproj │ Demonstrates the different kind of borders. │
|
||||||
│ Grid │ examples/Grid/Grid.csproj │ Demonstrates how to render grids in a console. │
|
│ Calendars │ examples/Calendars/Calendars.csproj │ Demonstrates how to render calendars. │
|
||||||
│ Panel │ examples/Panel/Panel.csproj │ Demonstrates how to render items in panels. │
|
│ Colors │ examples/Colors/Colors.csproj │ Demonstrates how to use colors in the console. │
|
||||||
│ Table │ examples/Table/Table.csproj │ Demonstrates how to render tables in a 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. │
|
||||||
|
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
|
||||||
```
|
```
|
||||||
|
|
||||||
And to run an example:
|
And to run an example:
|
||||||
|
|
||||||
```
|
```
|
||||||
> dotnet example table
|
> dotnet example tables
|
||||||
┌──────────┬──────────┬────────┐
|
┌──────────┬──────────┬────────┐
|
||||||
│ Foo │ Bar │ Baz │
|
│ Foo │ Bar │ Baz │
|
||||||
├──────────┼──────────┼────────┤
|
├──────────┼──────────┼────────┤
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
|
||||||
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
||||||
@@ -23,8 +23,20 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.5" />
|
<None Remove="src\Data\emojis.json" />
|
||||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.0" />
|
</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>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="Versioning" BeforeTargets="MinVer">
|
<Target Name="Versioning" BeforeTargets="MinVer">
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace Docs
|
|||||||
.ConfigureDeployment(deployBranch: "docs")
|
.ConfigureDeployment(deployBranch: "docs")
|
||||||
.AddShortcode("Children", typeof(ChildrenShortcode))
|
.AddShortcode("Children", typeof(ChildrenShortcode))
|
||||||
.AddShortcode("ColorTable", typeof(ColorTableShortcode))
|
.AddShortcode("ColorTable", typeof(ColorTableShortcode))
|
||||||
|
.AddShortcode("EmojiTable", typeof(EmojiTableShortcode))
|
||||||
.AddPipelines()
|
.AddPipelines()
|
||||||
.RunAsync();
|
.RunAsync();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,50 @@
|
|||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
Preview the documentation locally by running the following
|
To start contributing to the [Spectre.Console](https://github.com/spectresystems/spectre.console) documentation, you will need the [.NET Core SDK](https://dot.net) 3.1 or higher.
|
||||||
from your favourite shell:
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
```
|
```
|
||||||
> dotnet run -- preview --virtual-dir "spectre.console"
|
> dotnet run preview --virtual-dir "spectre.console"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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. Enhancements to the build process include:
|
||||||
|
|
||||||
|
- [Extension Methods](./src/Extensions)
|
||||||
|
- [Models](./src/Models)
|
||||||
|
- [Pipelines](./src/Pipelines)
|
||||||
|
- [Shortcodes](./src/Shortcodes)
|
||||||
|
- [Utilities](./src/Utilities)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Spectre Systems AB
|
||||||
|
|
||||||
|
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.
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<link href="/spectre.console/assets/bootstrap/bootstrap.css" rel="stylesheet" />
|
<link href="@Context.GetLink("/assets/bootstrap/bootstrap.css")" rel="stylesheet" />
|
||||||
<link href="/spectre.console/assets/css/styles.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 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">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.19.0/themes/prism.css">
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<nav id="topnav" class="navbar navbar-expand-lg navbar-light">
|
<nav id="topnav" class="navbar navbar-expand-lg navbar-light">
|
||||||
<div class="container py-3">
|
<div class="container py-3">
|
||||||
<a class="navbar-brand" href="/spectre.console"><img id="logo" src="/spectre.console/assets/logo.svg" alt="Spectre.Console"> Spectre.Console</a>
|
<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">
|
<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>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
@@ -128,14 +128,33 @@
|
|||||||
{
|
{
|
||||||
IDocument root = OutputPages["index.html"].First();
|
IDocument root = OutputPages["index.html"].First();
|
||||||
<div class="sidebar-nav-item @(Document.IdEquals(root) ? "active" : null)">
|
<div class="sidebar-nav-item @(Document.IdEquals(root) ? "active" : null)">
|
||||||
@Html.DocumentLink(root)
|
@if(root.ShowLink())
|
||||||
|
{
|
||||||
|
@Html.DocumentLink(root)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@root.GetTitle()
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
|
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
|
||||||
{
|
{
|
||||||
|
if(string.IsNullOrWhiteSpace(document.GetTitle()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
DocumentList<IDocument> documentChildren = OutputPages.GetChildrenOf(document);
|
DocumentList<IDocument> documentChildren = OutputPages.GetChildrenOf(document);
|
||||||
<div class="sidebar-nav-item @(Document.IdEquals(document) ? "active" : null) @(documentChildren.Any() ? "has-children" : null)">
|
<div class="sidebar-nav-item @(Document.IdEquals(document) ? "active" : null) @(documentChildren.Any() ? "has-children" : null)">
|
||||||
@Html.DocumentLink(document)
|
@if(document.ShowLink())
|
||||||
|
{
|
||||||
|
@Html.DocumentLink(document)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@document.GetTitle()
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (documentChildren.OnlyVisible().Any())
|
@if (documentChildren.OnlyVisible().Any())
|
||||||
|
|||||||
33
docs/input/appendix/borders.md
Normal 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;
|
||||||
|
```
|
||||||
31
docs/input/appendix/colors.md
Normal 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>
|
||||||
72
docs/input/appendix/emojis.md
Normal 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>
|
||||||
12
docs/input/appendix/index.cshtml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Title: Appendix
|
||||||
|
Order: 10
|
||||||
|
---
|
||||||
|
|
||||||
|
<h1>Sections</h1>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
|
||||||
|
{
|
||||||
|
<li>@Html.DocumentLink(child)</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
44
docs/input/appendix/styles.md
Normal 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>
|
||||||
BIN
docs/input/assets/images/borders/panel.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
docs/input/assets/images/borders/table.png
Normal file
|
After Width: | Height: | Size: 503 KiB |
BIN
docs/input/assets/images/compact_exception.png
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
docs/input/assets/images/custom_exception.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
BIN
docs/input/assets/images/exception.png
Normal file
|
After Width: | Height: | Size: 421 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
BIN
docs/input/assets/images/rule.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/input/assets/images/table.gif
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/input/assets/images/table.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
35
docs/input/assets/js/table-search.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
$(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
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
Title: Colors
|
|
||||||
Order: 4
|
|
||||||
---
|
|
||||||
|
|
||||||
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 /?>
|
|
||||||
52
docs/input/exceptions.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
Title: Exceptions
|
||||||
|
Order: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
Exceptions isn'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%;">
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Title: Welcome
|
Title: Welcome
|
||||||
Order: 0
|
Order: 0
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ for Python written by Will McGugan.
|
|||||||
The library will detect the capabilities of the current terminal
|
The library will detect the capabilities of the current terminal
|
||||||
and downgrade colors as needed.
|
and downgrade colors as needed.
|
||||||
|
|
||||||
## Example
|
## Examples
|
||||||
|
|
||||||
<img width="100%"
|
<img src="assets/images/table.gif" style="max-width: 100%; margin-top: 15px; margin-bottom: 25px;" />
|
||||||
src="https://github.com/spectresystems/spectre.console/raw/main/resources/gfx/screenshots/example.png" />
|
<img src="https://github.com/spectresystems/spectre.console/raw/main/resources/gfx/screenshots/example.png" style="max-width: 100%;" />
|
||||||
@@ -1,21 +1,18 @@
|
|||||||
Title: Markup
|
Title: Markup
|
||||||
Order: 3
|
Order: 2
|
||||||
Hidden: False
|
|
||||||
---
|
---
|
||||||
|
|
||||||
In `Spectre.Console` there's a class called `Markup` that
|
The class `Markup` allows you to output rich text to the console.
|
||||||
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
|
```csharp
|
||||||
AnsiConsole.Render(new Markup("[bold yellow]Hello[/] [red]World![/]"));
|
AnsiConsole.Render(new Markup("[bold yellow]Hello[/] [red]World![/]"));
|
||||||
```
|
```
|
||||||
|
|
||||||
Which should output something similar to the image below. Note that the
|
|
||||||
actual appearance might vary depending on your terminal.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
The `Markup` class implements `IRenderable` which means that you
|
The `Markup` class implements `IRenderable` which means that you
|
||||||
can use this in tables, grids, and panels. Most classes that support
|
can use this in tables, grids, and panels. Most classes that support
|
||||||
rendering of `IRenderable` also have overloads for rendering rich text.
|
rendering of `IRenderable` also have overloads for rendering rich text.
|
||||||
@@ -24,6 +21,7 @@ rendering of `IRenderable` also have overloads for rendering rich text.
|
|||||||
var table = new Table();
|
var table = new Table();
|
||||||
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
|
table.AddColumn(new TableColumn(new Markup("[yellow]Foo[/]")));
|
||||||
table.AddColumn(new TableColumn("[blue]Bar[/]"));
|
table.AddColumn(new TableColumn("[blue]Bar[/]"));
|
||||||
|
AnsiConsole.Render(table);
|
||||||
```
|
```
|
||||||
|
|
||||||
# Convenience methods
|
# Convenience methods
|
||||||
@@ -46,59 +44,49 @@ AnsiConsole.Markup("[[Hello]] "); // [Hello]
|
|||||||
AnsiConsole.Markup("[red][[World]][/]"); // [World]
|
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
|
# Setting background color
|
||||||
|
|
||||||
You can set the background color in markup by prefixing the color with
|
You can set the background color in markup by prefixing the color with
|
||||||
`on`.
|
`on`.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
AnsiConsole.Markup("[bold yellow on blue]Hello[/]");
|
||||||
|
AnsiConsole.Markup("[default on blue]World[/]");
|
||||||
```
|
```
|
||||||
[bold yellow on blue]Hello[/]
|
|
||||||
[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
|
# Colors
|
||||||
|
|
||||||
For a list of colors, see the [Colors](xref:colors) section.
|
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
|
# Styles
|
||||||
|
|
||||||
Note that what styles that can be used is defined by the system or your terminal software, and may not appear as they should.
|
For a list of styles, see the [Styles](xref:styles) appendix section.
|
||||||
|
|
||||||
<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>
|
|
||||||
99
docs/input/prompt.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
Title: Prompt
|
||||||
|
Order: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
Sometimes you want to get some input from the user, and for this
|
||||||
|
you can use the `Prompt<TResult>`.
|
||||||
|
|
||||||
|
# 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? _
|
||||||
|
```
|
||||||
121
docs/input/widgets/calendar.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
Title: Calendar
|
||||||
|
Order: 4
|
||||||
|
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);
|
||||||
|
```
|
||||||
3
docs/input/widgets/index.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Title: Widgets
|
||||||
|
Order: 9
|
||||||
|
---
|
||||||
72
docs/input/widgets/rule.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
Title: Rule
|
||||||
|
Order: 5
|
||||||
|
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
@@ -0,0 +1,136 @@
|
|||||||
|
Title: Table
|
||||||
|
Order: 3
|
||||||
|
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 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);
|
||||||
|
```
|
||||||
@@ -1,14 +1,20 @@
|
|||||||
namespace Docs
|
namespace Docs
|
||||||
{
|
{
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public const string NoContainer = nameof(NoContainer);
|
public const string NoContainer = nameof(NoContainer);
|
||||||
public const string NoSidebar = nameof(NoSidebar);
|
public const string NoSidebar = nameof(NoSidebar);
|
||||||
|
public const string NoLink = nameof(NoLink);
|
||||||
public const string Topic = nameof(Topic);
|
public const string Topic = nameof(Topic);
|
||||||
public const string EditLink = nameof(EditLink);
|
public const string EditLink = nameof(EditLink);
|
||||||
public const string Description = nameof(Description);
|
public const string Description = nameof(Description);
|
||||||
public const string Hidden = nameof(Hidden);
|
public const string Hidden = nameof(Hidden);
|
||||||
|
|
||||||
|
public static class Emojis
|
||||||
|
{
|
||||||
|
public const string Root = "EMOJIS_ROOT";
|
||||||
|
}
|
||||||
|
|
||||||
public static class Colors
|
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/spectresystems/spectre.console/main/resources/scripts/Generator/Data/colors.json";
|
||||||
|
|||||||
7946
docs/src/Data/emojis.json
Normal file
@@ -20,10 +20,7 @@ namespace Docs
|
|||||||
|
|
||||||
public static Bootstrapper ConfigureDeployment(this Bootstrapper bootstrapper, string deployBranch)
|
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;
|
return bootstrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Statiq.Common;
|
using Statiq.Common;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -16,6 +16,11 @@ namespace Docs
|
|||||||
return !document.GetBool(Constants.Hidden, false);
|
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)
|
public static IEnumerable<IDocument> OnlyVisible(this IEnumerable<IDocument> source)
|
||||||
{
|
{
|
||||||
return source.Where(x => x.IsVisible());
|
return source.Where(x => x.IsVisible());
|
||||||
|
|||||||
20
docs/src/Models/Emoji.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
docs/src/Modules/ReadEmbedded.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,15 +9,13 @@ namespace Docs.Pipelines
|
|||||||
{
|
{
|
||||||
public class ColorsPipeline : Pipeline
|
public class ColorsPipeline : Pipeline
|
||||||
{
|
{
|
||||||
public const string Url = "https://raw.githubusercontent.com/spectresystems/spectre.console/main/resources/scripts/Generator/Data/colors.json";
|
|
||||||
|
|
||||||
public ColorsPipeline()
|
public ColorsPipeline()
|
||||||
{
|
{
|
||||||
InputModules = new ModuleList
|
InputModules = new ModuleList
|
||||||
{
|
{
|
||||||
new ExecuteConfig(
|
new ExecuteConfig(
|
||||||
Config.FromContext(ctx => {
|
Config.FromContext(ctx => {
|
||||||
return new ReadWeb(Url);
|
return new ReadWeb(Constants.Colors.Url);
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,15 +24,10 @@ namespace Docs.Pipelines
|
|||||||
new ExecuteConfig(
|
new ExecuteConfig(
|
||||||
Config.FromDocument(async (doc, ctx) =>
|
Config.FromDocument(async (doc, ctx) =>
|
||||||
{
|
{
|
||||||
var colors = Color.Parse(await doc.GetContentStringAsync()).ToList();
|
var data = Color.Parse(await doc.GetContentStringAsync()).ToList();
|
||||||
var definitions = new List<IDocument> { colors.ToDocument(Constants.Colors.Root) };
|
return data.ToDocument(Constants.Colors.Root);
|
||||||
|
|
||||||
return doc.Clone(new MetadataDictionary
|
|
||||||
{
|
|
||||||
[Constants.Colors.Root] = definitions
|
|
||||||
});
|
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
docs/src/Pipelines/EmojiPipeline.cs
Normal 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);
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,12 +17,11 @@ namespace Docs.Shortcodes
|
|||||||
// Get the definition.
|
// Get the definition.
|
||||||
var colors = context.Outputs
|
var colors = context.Outputs
|
||||||
.FromPipeline(nameof(ColorsPipeline))
|
.FromPipeline(nameof(ColorsPipeline))
|
||||||
.First()
|
|
||||||
.GetChildren(Constants.Colors.Root)
|
|
||||||
.OfType<ObjectDocument<List<Color>>>()
|
.OfType<ObjectDocument<List<Color>>>()
|
||||||
.First().Object;
|
.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"));
|
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", "#"));
|
header.Add(new XElement("th", "#"));
|
||||||
@@ -34,8 +33,8 @@ namespace Docs.Shortcodes
|
|||||||
|
|
||||||
foreach (var color in colors)
|
foreach (var color in colors)
|
||||||
{
|
{
|
||||||
var rep = new XElement("td",
|
var rep = new XElement("td",
|
||||||
new XElement("span",
|
new XElement("span",
|
||||||
new XAttribute("class", "color-representation"),
|
new XAttribute("class", "color-representation"),
|
||||||
new XAttribute("style", $"background-color:{color.Hex};")));
|
new XAttribute("style", $"background-color:{color.Hex};")));
|
||||||
var name = new XElement("td", new XElement("code", color.Number.ToString()));
|
var name = new XElement("td", new XElement("code", color.Number.ToString()));
|
||||||
@@ -45,7 +44,7 @@ namespace Docs.Shortcodes
|
|||||||
var clr = new XElement("td", new XElement("code", color.ClrName));
|
var clr = new XElement("td", new XElement("code", color.ClrName));
|
||||||
|
|
||||||
// Create row
|
// Create row
|
||||||
var row = new XElement("tr");
|
var row = new XElement("tr", new XAttribute("class", "search-row"));
|
||||||
row.Add(rep);
|
row.Add(rep);
|
||||||
row.Add(name);
|
row.Add(name);
|
||||||
row.Add(number);
|
row.Add(number);
|
||||||
|
|||||||
45
docs/src/Shortcodes/EmojiTableShortcode.cs
Normal 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("&#x", "&#x");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"cake.tool": {
|
"cake.tool": {
|
||||||
"version": "0.38.4",
|
"version": "1.0.0-rc0001",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-cake"
|
"dotnet-cake"
|
||||||
]
|
]
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dotnet-example": {
|
"dotnet-example": {
|
||||||
"version": "0.8.0",
|
"version": "1.1.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-example"
|
"dotnet-example"
|
||||||
]
|
]
|
||||||
|
|||||||
15
examples/Borders/Borders.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Borders</Title>
|
||||||
|
<Description>Demonstrates the different kind of borders.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
91
examples/Borders/Program.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
|
namespace BordersExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
// Render panel borders
|
||||||
|
HorizontalRule("PANEL BORDERS");
|
||||||
|
PanelBorders();
|
||||||
|
|
||||||
|
// Render table borders
|
||||||
|
HorizontalRule("TABLE BORDERS");
|
||||||
|
TableBorders();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PanelBorders()
|
||||||
|
{
|
||||||
|
static IRenderable CreatePanel(string name, BoxBorder border)
|
||||||
|
{
|
||||||
|
return new Panel($"This is a panel with\nthe [yellow]{name}[/] border.")
|
||||||
|
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||||
|
.Border(border)
|
||||||
|
.BorderStyle(Style.Parse("grey"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = new[]
|
||||||
|
{
|
||||||
|
CreatePanel("Ascii", BoxBorder.Ascii),
|
||||||
|
CreatePanel("Square", BoxBorder.Square),
|
||||||
|
CreatePanel("Rounded", BoxBorder.Rounded),
|
||||||
|
CreatePanel("Heavy", BoxBorder.Heavy),
|
||||||
|
CreatePanel("Double", BoxBorder.Double),
|
||||||
|
CreatePanel("None", BoxBorder.None),
|
||||||
|
};
|
||||||
|
|
||||||
|
AnsiConsole.Render(
|
||||||
|
new Padder(
|
||||||
|
new Columns(items).PadRight(2),
|
||||||
|
new Padding(2,0,0,0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void TableBorders()
|
||||||
|
{
|
||||||
|
static IRenderable CreateTable(string name, TableBorder border)
|
||||||
|
{
|
||||||
|
var table = new Table().Border(border);
|
||||||
|
table.AddColumn("[yellow]Header 1[/]", c => c.Footer("[grey]Footer 1[/]"));
|
||||||
|
table.AddColumn("[yellow]Header 2[/]", col => col.Footer("[grey]Footer 2[/]").RightAligned());
|
||||||
|
table.AddRow("Cell", "Cell");
|
||||||
|
table.AddRow("Cell", "Cell");
|
||||||
|
|
||||||
|
return new Panel(table)
|
||||||
|
.Header($" [blue]{name}[/] ", Justify.Center)
|
||||||
|
.NoBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = new[]
|
||||||
|
{
|
||||||
|
CreateTable("Ascii", TableBorder.Ascii),
|
||||||
|
CreateTable("Ascii2", TableBorder.Ascii2),
|
||||||
|
CreateTable("AsciiDoubleHead", TableBorder.AsciiDoubleHead),
|
||||||
|
CreateTable("Horizontal", TableBorder.Horizontal),
|
||||||
|
CreateTable("Simple", TableBorder.Simple),
|
||||||
|
CreateTable("SimpleHeavy", TableBorder.SimpleHeavy),
|
||||||
|
CreateTable("Minimal", TableBorder.Minimal),
|
||||||
|
CreateTable("MinimalHeavyHead", TableBorder.MinimalHeavyHead),
|
||||||
|
CreateTable("MinimalDoubleHead", TableBorder.MinimalDoubleHead),
|
||||||
|
CreateTable("Square", TableBorder.Square),
|
||||||
|
CreateTable("Rounded", TableBorder.Rounded),
|
||||||
|
CreateTable("Heavy", TableBorder.Heavy),
|
||||||
|
CreateTable("HeavyEdge", TableBorder.HeavyEdge),
|
||||||
|
CreateTable("HeavyHead", TableBorder.HeavyHead),
|
||||||
|
CreateTable("Double", TableBorder.Double),
|
||||||
|
CreateTable("DoubleEdge", TableBorder.DoubleEdge),
|
||||||
|
CreateTable("Markdown", TableBorder.Markdown),
|
||||||
|
};
|
||||||
|
|
||||||
|
AnsiConsole.Render(new Columns(items).Collapse());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HorizontalRule(string title)
|
||||||
|
{
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule($"[white bold]{title}[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
examples/Calendars/Calendars.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Calendars</Title>
|
||||||
|
<Description>Demonstrates how to render calendars.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
19
examples/Calendars/Program.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace Calendars
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Calendar(2020, 10)
|
||||||
|
.RoundedBorder()
|
||||||
|
.HighlightStyle(Style.Parse("red"))
|
||||||
|
.HeaderStyle(Style.Parse("yellow"))
|
||||||
|
.AddCalendarEvent("An event", 2020, 9, 22)
|
||||||
|
.AddCalendarEvent("Another event", 2020, 10, 2)
|
||||||
|
.AddCalendarEvent("A third event", 2020, 10, 13));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Colors</Title>
|
||||||
<Description>Demonstrates how to use [yellow]c[/][red]o[/][green]l[/][blue]o[/][aqua]r[/][lime]s[/] in the console.</Description>
|
<Description>Demonstrates how to use [yellow]c[/][red]o[/][green]l[/][blue]o[/][aqua]r[/][lime]s[/] in the console.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace ColorExample
|
|||||||
|
|
||||||
AnsiConsole.ResetColors();
|
AnsiConsole.ResetColors();
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.MarkupLine("[bold underline]3-bit Colors[/]");
|
AnsiConsole.Render(new Rule("[yellow bold underline]3-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
|
|
||||||
for (var i = 0; i < 8; i++)
|
for (var i = 0; i < 8; i++)
|
||||||
@@ -47,7 +47,7 @@ namespace ColorExample
|
|||||||
|
|
||||||
AnsiConsole.ResetColors();
|
AnsiConsole.ResetColors();
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.MarkupLine("[bold underline]4-bit Colors[/]");
|
AnsiConsole.Render(new Rule("[yellow bold underline]4-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
|
|
||||||
for (var i = 0; i < 16; i++)
|
for (var i = 0; i < 16; i++)
|
||||||
@@ -70,7 +70,7 @@ namespace ColorExample
|
|||||||
|
|
||||||
AnsiConsole.ResetColors();
|
AnsiConsole.ResetColors();
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.MarkupLine("[bold underline]8-bit Colors[/]");
|
AnsiConsole.Render(new Rule("[yellow bold underline]8-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
|
|
||||||
for (var i = 0; i < 16; i++)
|
for (var i = 0; i < 16; i++)
|
||||||
@@ -97,7 +97,7 @@ namespace ColorExample
|
|||||||
|
|
||||||
AnsiConsole.ResetColors();
|
AnsiConsole.ResetColors();
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.MarkupLine("[bold underline]24-bit Colors[/]");
|
AnsiConsole.Render(new Rule("[yellow bold underline]24-bit Colors[/]").RuleStyle("grey").LeftAligned());
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
|
|
||||||
var index = 0;
|
var index = 0;
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Columns</Title>
|
||||||
<Description>Demonstrates how to render data into columns.</Description>
|
<Description>Demonstrates how to render data into columns.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
@@ -21,8 +19,8 @@ namespace ColumnsExample
|
|||||||
var cards = new List<Panel>();
|
var cards = new List<Panel>();
|
||||||
foreach(var user in users.results)
|
foreach(var user in users.results)
|
||||||
{
|
{
|
||||||
cards.Add(new Panel(GetCard(user))
|
cards.Add(new Panel(GetCardContent(user))
|
||||||
.SetHeader($"{user.location.country}")
|
.Header($"{user.location.country}")
|
||||||
.RoundedBorder().Expand());
|
.RoundedBorder().Expand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +28,7 @@ namespace ColumnsExample
|
|||||||
AnsiConsole.Render(new Columns(cards));
|
AnsiConsole.Render(new Columns(cards));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCard(dynamic user)
|
private static string GetCardContent(dynamic user)
|
||||||
{
|
{
|
||||||
var name = $"{user.name.first} {user.name.last}";
|
var name = $"{user.name.first} {user.name.last}";
|
||||||
var country = $"{user.location.city}";
|
var country = $"{user.location.city}";
|
||||||
|
|||||||
15
examples/Cursor/Cursor.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Cursor</Title>
|
||||||
|
<Description>Demonstrates how to move the cursor.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
20
examples/Cursor/Program.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace Cursor
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
AnsiConsole.Write("Hello");
|
||||||
|
|
||||||
|
// Move the cursor 3 cells to the right
|
||||||
|
AnsiConsole.Cursor.Move(CursorDirection.Right, 3);
|
||||||
|
AnsiConsole.Write("World");
|
||||||
|
|
||||||
|
// Move the cursor 5 cells to the left.
|
||||||
|
AnsiConsole.Cursor.Move(CursorDirection.Left, 5);
|
||||||
|
AnsiConsole.WriteLine("Universe");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
examples/Emojis/Emojis.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Emojis</Title>
|
||||||
|
<Description>Demonstrates how to render emojis.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
24
examples/Emojis/Program.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace EmojiExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// Show a known emoji
|
||||||
|
RenderEmoji();
|
||||||
|
|
||||||
|
// Show a remapped emoji
|
||||||
|
Emoji.Remap("globe_showing_europe_africa", Emoji.Known.GrinningFaceWithSmilingEyes);
|
||||||
|
RenderEmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RenderEmoji()
|
||||||
|
{
|
||||||
|
AnsiConsole.Render(
|
||||||
|
new Panel("[yellow]Hello :globe_showing_europe_africa:![/]")
|
||||||
|
.RoundedBorder());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
examples/Exceptions/Exceptions.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Exceptions</Title>
|
||||||
|
<Description>Demonstrates how to render formatted exceptions.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
66
examples/Exceptions/Program.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Security.Authentication;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace Exceptions
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DoMagic(42, null);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("Default").LeftAligned());
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.WriteException(ex);
|
||||||
|
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("Compact").LeftAligned());
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks);
|
||||||
|
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("Compact + Custom colors").LeftAligned());
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoMagic(int foo, string[,] bar)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CheckCredentials(foo, bar);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Whaaat?", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckCredentials(int qux, string[,] corgi)
|
||||||
|
{
|
||||||
|
throw new InvalidCredentialException("The credentials are invalid.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Grids</Title>
|
||||||
<Description>Demonstrates how to render grids in a console.</Description>
|
<Description>Demonstrates how to render grids in a console.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
|
|
||||||
namespace GridExample
|
namespace GridExample
|
||||||
{
|
{
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static void Main()
|
public static void Main()
|
||||||
{
|
{
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
AnsiConsole.MarkupLine("Usage: [grey]dotnet [blue]run[/] [[options]] [[[[--]] <additional arguments>...]]]][/]");
|
AnsiConsole.MarkupLine("Usage: [grey]dotnet [blue]run[/] [[options]] [[[[--]] <additional arguments>...]]]][/]");
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
|
|
||||||
var grid = new Grid();
|
var grid = new Grid();
|
||||||
grid.AddColumn(new GridColumn { NoWrap = true });
|
grid.AddColumn(new GridColumn().NoWrap());
|
||||||
grid.AddColumn(new GridColumn { NoWrap = true, Width = 2 });
|
grid.AddColumn(new GridColumn().PadLeft(2));
|
||||||
grid.AddColumn();
|
grid.AddRow("Options:");
|
||||||
grid.AddRow("Options:", "", "");
|
grid.AddRow(" [blue]-h[/], [blue]--help[/]", "Show command line help.");
|
||||||
grid.AddRow(" [blue]-h[/], [blue]--help[/]", "", "Show command line help.");
|
grid.AddRow(" [blue]-c[/], [blue]--configuration[/] <CONFIGURATION>", "The configuration to run for.");
|
||||||
grid.AddRow(" [blue]-c[/], [blue]--configuration[/] <CONFIGURATION>", "", "The configuration to run for.");
|
grid.AddRow(" [blue]-v[/], [blue]--verbosity[/] <LEVEL>", "Set the [grey]MSBuild[/] verbosity level.");
|
||||||
grid.AddRow(" [blue]-v[/], [blue]--verbosity[/] <LEVEL>", "", "Set the [grey]MSBuild[/] verbosity level.");
|
|
||||||
|
AnsiConsole.Render(grid);
|
||||||
AnsiConsole.Render(grid);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Info</Title>
|
||||||
<Description>Displays the capabilities of the current console.</Description>
|
<Description>Displays the capabilities of the current console.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
using System;
|
||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
|
|
||||||
namespace Info
|
namespace InfoExample
|
||||||
{
|
{
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
@@ -10,14 +11,20 @@ namespace Info
|
|||||||
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
||||||
.AddColumn()
|
.AddColumn()
|
||||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
||||||
.AddRow("[b]Supports ansi?[/]", $"{AnsiConsole.Capabilities.SupportsAnsi}")
|
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsAnsi)}")
|
||||||
.AddRow("[b]Legacy console?[/]", $"{AnsiConsole.Capabilities.LegacyConsole}")
|
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Capabilities.LegacyConsole)}")
|
||||||
|
.AddRow("[b]Interactive?[/]", $"{YesNo(Environment.UserInteractive)}")
|
||||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
||||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
||||||
|
|
||||||
AnsiConsole.Render(
|
AnsiConsole.Render(
|
||||||
new Panel(grid)
|
new Panel(grid)
|
||||||
.SetHeader("Information"));
|
.Header("Information"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string YesNo(bool value)
|
||||||
|
{
|
||||||
|
return value ? "Yes" : "No";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
examples/Links/Links.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Links</Title>
|
||||||
|
<Description>Demonstrates how to render links in a console.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
21
examples/Links/Program.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace LinkExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
if (AnsiConsole.Capabilities.SupportLinks)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine("[link=https://patriksvensson.se]Click to visit my blog[/]!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine("[red]It looks like your terminal doesn't support links[/]");
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.MarkupLine("[yellow](╯°□°)╯[/]︵ [blue]┻━┻[/]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Panels</Title>
|
||||||
<Description>Demonstrates how to render items in panels.</Description>
|
<Description>Demonstrates how to render items in panels.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
using Spectre.Console.Rendering;
|
|
||||||
|
|
||||||
namespace PanelExample
|
namespace PanelExample
|
||||||
{
|
{
|
||||||
@@ -14,28 +13,30 @@ namespace PanelExample
|
|||||||
AnsiConsole.Render(
|
AnsiConsole.Render(
|
||||||
new Panel(
|
new Panel(
|
||||||
new Panel(content)
|
new Panel(content)
|
||||||
.SetBorderKind(BorderKind.Rounded)));
|
.Border(BoxBorder.Rounded)));
|
||||||
|
|
||||||
// Left adjusted panel with text
|
// Left adjusted panel with text
|
||||||
AnsiConsole.Render(
|
AnsiConsole.Render(
|
||||||
new Panel(new Text("Left adjusted\nLeft").LeftAligned())
|
new Panel(new Text("Left adjusted\nLeft").LeftAligned())
|
||||||
.Expand()
|
.Expand()
|
||||||
.SquareBorder()
|
.SquareBorder()
|
||||||
.SetHeader("Left", Style.WithForeground(Color.Red)));
|
.Header("[red]Left[/]"));
|
||||||
|
|
||||||
// Centered ASCII panel with text
|
// Centered ASCII panel with text
|
||||||
AnsiConsole.Render(
|
AnsiConsole.Render(
|
||||||
new Panel(new Text("Centered\nCenter").Centered())
|
new Panel(new Text("Centered\nCenter").Centered())
|
||||||
.Expand()
|
.Expand()
|
||||||
.AsciiBorder()
|
.AsciiBorder()
|
||||||
.SetHeader("Center", Style.WithForeground(Color.Green), Justify.Center));
|
.Header("[green]Center[/]")
|
||||||
|
.HeaderAlignment(Justify.Center));
|
||||||
|
|
||||||
// Right adjusted, rounded panel with text
|
// Right adjusted, rounded panel with text
|
||||||
AnsiConsole.Render(
|
AnsiConsole.Render(
|
||||||
new Panel(new Text("Right adjusted\nRight").RightAligned())
|
new Panel(new Text("Right adjusted\nRight").RightAligned())
|
||||||
.Expand()
|
.Expand()
|
||||||
.RoundedBorder()
|
.RoundedBorder()
|
||||||
.SetHeader("Right", Style.WithForeground(Color.Blue), Justify.Right));
|
.Header("[blue]Right[/]")
|
||||||
|
.HeaderAlignment(Justify.Right));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
77
examples/Prompt/Program.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace Cursor
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// Confirmation
|
||||||
|
if (!AnsiConsole.Confirm("Run prompt example?"))
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine("Ok... :(");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// String
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("[yellow]Strings[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
var name = AnsiConsole.Ask<string>("What's your [green]name[/]?");
|
||||||
|
|
||||||
|
// String with choices
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("[yellow]Choices[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
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"));
|
||||||
|
|
||||||
|
// Integer
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("[yellow]Integers[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
var age = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<int>("How [green]old[/] are you?")
|
||||||
|
.PromptStyle("green")
|
||||||
|
.ValidationErrorMessage("[red]That's not a valid age[/]")
|
||||||
|
.Validate(age =>
|
||||||
|
{
|
||||||
|
return age switch
|
||||||
|
{
|
||||||
|
<= 0 => ValidationResult.Error("[red]You must at least be 1 years old[/]"),
|
||||||
|
>= 123 => ValidationResult.Error("[red]You must be younger than the oldest person alive[/]"),
|
||||||
|
_ => ValidationResult.Success(),
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Secret
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("[yellow]Secrets[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
var password = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("Enter [green]password[/]?")
|
||||||
|
.PromptStyle("red")
|
||||||
|
.Secret());
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("[yellow]Optional[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
var color = AnsiConsole.Prompt(
|
||||||
|
new TextPrompt<string>("[grey][[Optional]][/] What is your [green]favorite color[/]?")
|
||||||
|
.AllowEmpty());
|
||||||
|
|
||||||
|
// Summary
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
AnsiConsole.Render(new Rule("[yellow]Results[/]").RuleStyle("grey").LeftAligned());
|
||||||
|
AnsiConsole.Render(new Table().AddColumns("[grey]Question[/]", "[grey]Answer[/]")
|
||||||
|
.RoundedBorder()
|
||||||
|
.BorderColor(Color.Grey)
|
||||||
|
.AddRow("[grey]Name[/]", name)
|
||||||
|
.AddRow("[grey]Favorite fruit[/]", fruit)
|
||||||
|
.AddRow("[grey]Age[/]", age.ToString())
|
||||||
|
.AddRow("[grey]Password[/]", password)
|
||||||
|
.AddRow("[grey]Favorite color[/]", string.IsNullOrEmpty(color) ? "Unknown" : color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
examples/Prompt/Prompt.csproj
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<LangVersion>9</LangVersion>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Prompt</Title>
|
||||||
|
<Description>Demonstrates how to get input from a user.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
43
examples/Rules/Program.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace EmojiExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// No title
|
||||||
|
WrapInPanel(
|
||||||
|
new Rule()
|
||||||
|
.RuleStyle(Style.Parse("yellow"))
|
||||||
|
.AsciiBorder()
|
||||||
|
.LeftAligned());
|
||||||
|
|
||||||
|
// Left aligned title
|
||||||
|
WrapInPanel(
|
||||||
|
new Rule("[blue]Left aligned[/]")
|
||||||
|
.RuleStyle(Style.Parse("red"))
|
||||||
|
.DoubleBorder()
|
||||||
|
.LeftAligned());
|
||||||
|
|
||||||
|
// Centered title
|
||||||
|
WrapInPanel(
|
||||||
|
new Rule("[green]Centered[/]")
|
||||||
|
.RuleStyle(Style.Parse("green"))
|
||||||
|
.HeavyBorder()
|
||||||
|
.Centered());
|
||||||
|
|
||||||
|
// Right aligned title
|
||||||
|
WrapInPanel(
|
||||||
|
new Rule("[red]Right aligned[/]")
|
||||||
|
.RuleStyle(Style.Parse("blue"))
|
||||||
|
.RightAligned());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WrapInPanel(Rule rule)
|
||||||
|
{
|
||||||
|
AnsiConsole.Render(rule);
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
examples/Rules/Rules.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Rules</Title>
|
||||||
|
<Description>Demonstrates how to render horizontal rules (lines).</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
using Spectre.Console;
|
|
||||||
|
|
||||||
namespace TableExample
|
|
||||||
{
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
public static void Main()
|
|
||||||
{
|
|
||||||
// A simple table
|
|
||||||
RenderSimpleTable();
|
|
||||||
|
|
||||||
// A big table
|
|
||||||
RenderBigTable();
|
|
||||||
|
|
||||||
// A nested table
|
|
||||||
RenderNestedTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RenderSimpleTable()
|
|
||||||
{
|
|
||||||
// Create the table.
|
|
||||||
var table = new Table();
|
|
||||||
table.AddColumn(new TableColumn("[u]Foo[/]"));
|
|
||||||
table.AddColumn(new TableColumn("[u]Bar[/]"));
|
|
||||||
table.AddColumn(new TableColumn("[u]Baz[/]"));
|
|
||||||
|
|
||||||
// Add some rows
|
|
||||||
table.AddRow("Hello", "[red]World![/]", "");
|
|
||||||
table.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]");
|
|
||||||
table.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
|
||||||
|
|
||||||
AnsiConsole.Render(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RenderBigTable()
|
|
||||||
{
|
|
||||||
// Create the table.
|
|
||||||
var table = new Table().SetBorderKind(BorderKind.Rounded);
|
|
||||||
table.AddColumn("[red underline]Foo[/]");
|
|
||||||
table.AddColumn(new TableColumn("[blue]Bar[/]") { Alignment = Justify.Right, NoWrap = true });
|
|
||||||
|
|
||||||
// Add some rows
|
|
||||||
table.AddRow("[blue][underline]Hell[/]o[/]", "World");
|
|
||||||
table.AddRow("[yellow]Patrik [green]\"Hello World\"[/] Svensson[/]", "Was [underline]here[/]!");
|
|
||||||
table.AddEmptyRow();
|
|
||||||
table.AddRow(
|
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
|
|
||||||
"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
|
|
||||||
"dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " +
|
|
||||||
"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", "<- Strange language");
|
|
||||||
table.AddEmptyRow();
|
|
||||||
table.AddRow("Hej", "[green]Världen[/]");
|
|
||||||
|
|
||||||
AnsiConsole.Render(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RenderNestedTable()
|
|
||||||
{
|
|
||||||
// Create simple table.
|
|
||||||
var simple = new Table().SetBorderKind(BorderKind.Rounded).SetBorderColor(Color.Red);
|
|
||||||
simple.AddColumn(new TableColumn("[u]Foo[/]").Centered());
|
|
||||||
simple.AddColumn(new TableColumn("[u]Bar[/]"));
|
|
||||||
simple.AddColumn(new TableColumn("[u]Baz[/]"));
|
|
||||||
simple.AddRow("Hello", "[red]World![/]", "");
|
|
||||||
simple.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]");
|
|
||||||
simple.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
|
||||||
|
|
||||||
// Create other table.
|
|
||||||
var second = new Table().SetBorderKind(BorderKind.Square).SetBorderColor(Color.Green);
|
|
||||||
second.AddColumn(new TableColumn("[u]Foo[/]"));
|
|
||||||
second.AddColumn(new TableColumn("[u]Bar[/]"));
|
|
||||||
second.AddColumn(new TableColumn("[u]Baz[/]"));
|
|
||||||
second.AddRow("Hello", "[red]World![/]", "");
|
|
||||||
second.AddRow(simple, new Text("Whaaat"), new Text("Lolz"));
|
|
||||||
second.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
|
||||||
|
|
||||||
var table = new Table().SetBorderKind(BorderKind.Rounded);
|
|
||||||
table.AddColumn(new TableColumn(new Panel("[u]Foo[/]").SetBorderColor(Color.Red)));
|
|
||||||
table.AddColumn(new TableColumn(new Panel("[u]Bar[/]").SetBorderColor(Color.Green)));
|
|
||||||
table.AddColumn(new TableColumn(new Panel("[u]Baz[/]").SetBorderColor(Color.Blue)));
|
|
||||||
|
|
||||||
// Add some rows
|
|
||||||
table.AddRow(new Text("Hello").Centered(), new Markup("[red]World![/]"), Text.Empty);
|
|
||||||
table.AddRow(second, new Text("Whaaat"), new Text("Lol"));
|
|
||||||
table.AddRow(new Markup("[blue]Hej[/]").Centered(), new Markup("[yellow]Världen![/]"), Text.Empty);
|
|
||||||
|
|
||||||
AnsiConsole.Render(table);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
51
examples/Tables/Program.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace TableExample
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
// Create the table.
|
||||||
|
var table = CreateTable();
|
||||||
|
|
||||||
|
// Render the table.
|
||||||
|
AnsiConsole.Render(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Table CreateTable()
|
||||||
|
{
|
||||||
|
var simple = new Table()
|
||||||
|
.Border(TableBorder.Square)
|
||||||
|
.BorderColor(Color.Red)
|
||||||
|
.AddColumn(new TableColumn("[u]CDE[/]").Footer("EDC").Centered())
|
||||||
|
.AddColumn(new TableColumn("[u]FED[/]").Footer("DEF"))
|
||||||
|
.AddColumn(new TableColumn("[u]IHG[/]").Footer("GHI"))
|
||||||
|
.AddRow("Hello", "[red]World![/]", "")
|
||||||
|
.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]")
|
||||||
|
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||||
|
|
||||||
|
var second = new Table()
|
||||||
|
.Border(TableBorder.Rounded)
|
||||||
|
.BorderColor(Color.Green)
|
||||||
|
.AddColumn(new TableColumn("[u]Foo[/]"))
|
||||||
|
.AddColumn(new TableColumn("[u]Bar[/]"))
|
||||||
|
.AddColumn(new TableColumn("[u]Baz[/]"))
|
||||||
|
.AddRow("Hello", "[red]World![/]", "")
|
||||||
|
.AddRow(simple, new Text("Whaaat"), new Text("Lolz"))
|
||||||
|
.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
|
||||||
|
|
||||||
|
return new Table()
|
||||||
|
.Centered()
|
||||||
|
.Border(TableBorder.DoubleEdge)
|
||||||
|
.Title("TABLE [yellow]TITLE[/]")
|
||||||
|
.Caption("TABLE [yellow]CAPTION[/]")
|
||||||
|
.AddColumn(new TableColumn(new Panel("[u]ABC[/]").BorderColor(Color.Red)).Footer("[u]FOOTER 1[/]"))
|
||||||
|
.AddColumn(new TableColumn(new Panel("[u]DEF[/]").BorderColor(Color.Green)).Footer("[u]FOOTER 2[/]"))
|
||||||
|
.AddColumn(new TableColumn(new Panel("[u]GHI[/]").BorderColor(Color.Blue)).Footer("[u]FOOTER 3[/]"))
|
||||||
|
.AddRow(new Text("Hello").Centered(), new Markup("[red]World![/]"), Text.Empty)
|
||||||
|
.AddRow(second, new Text("Whaaat"), new Text("Lol"))
|
||||||
|
.AddRow(new Markup("[blue]Hej[/]").Centered(), new Markup("[yellow]Världen![/]"), Text.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
<Title>Tables</Title>
|
||||||
<Description>Demonstrates how to render tables in a console.</Description>
|
<Description>Demonstrates how to render tables in a console.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"projects": [ "src" ],
|
"projects": [ "src" ],
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "3.1.301",
|
"version": "5.0.100",
|
||||||
"rollForward": "latestMajor"
|
"rollForward": "latestPatch"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
##########################################################
|
##########################################################
|
||||||
|
|
||||||
$Output = Join-Path $PSScriptRoot "Temp"
|
$Output = Join-Path $PSScriptRoot "Temp"
|
||||||
$Source = Join-Path $PSScriptRoot "/../src/Spectre.Console"
|
$Source = Join-Path $PSScriptRoot "/../../src/Spectre.Console"
|
||||||
|
|
||||||
if(!(Test-Path $Output -PathType Container)) {
|
if(!(Test-Path $Output -PathType Container)) {
|
||||||
New-Item -ItemType Directory -Path $Output | Out-Null
|
New-Item -ItemType Directory -Path $Output | Out-Null
|
||||||
|
|||||||
24
resources/scripts/Generate-Emoji.ps1
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
##########################################################
|
||||||
|
# Script that generates the emoji lookup table.
|
||||||
|
##########################################################
|
||||||
|
|
||||||
|
$Output = Join-Path $PSScriptRoot "Temp"
|
||||||
|
$Source = Join-Path $PSScriptRoot "/../../src/Spectre.Console"
|
||||||
|
$Docs = Join-Path $PSScriptRoot "/../../docs/src/Data"
|
||||||
|
|
||||||
|
if(!(Test-Path $Output -PathType Container)) {
|
||||||
|
New-Item -ItemType Directory -Path $Output | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate the files
|
||||||
|
Push-Location Generator
|
||||||
|
&dotnet run -- emoji "$Output" --input $Output
|
||||||
|
if(!$?) {
|
||||||
|
Pop-Location
|
||||||
|
Throw "An error occured when generating code."
|
||||||
|
}
|
||||||
|
Pop-Location
|
||||||
|
|
||||||
|
# Copy the files to the correct location
|
||||||
|
Copy-Item (Join-Path "$Output" "Emoji.Generated.cs") -Destination "$Source/Emoji.Generated.cs"
|
||||||
|
Copy-Item (Join-Path "$Output" "emojis.json") -Destination "$Docs/emojis.json"
|
||||||
@@ -55,5 +55,8 @@ namespace Generator.Commands
|
|||||||
{
|
{
|
||||||
[CommandArgument(0, "<OUTPUT>")]
|
[CommandArgument(0, "<OUTPUT>")]
|
||||||
public string Output { get; set; }
|
public string Output { get; set; }
|
||||||
|
|
||||||
|
[CommandOption("-i|--input <PATH>")]
|
||||||
|
public string Input { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
101
resources/scripts/Generator/Commands/EmojiGeneratorCommand.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AngleSharp.Html.Parser;
|
||||||
|
using Generator.Models;
|
||||||
|
using Scriban;
|
||||||
|
using Scriban.Runtime;
|
||||||
|
using Spectre.Cli;
|
||||||
|
using Spectre.IO;
|
||||||
|
using Path = Spectre.IO.Path;
|
||||||
|
using SpectreEnvironment = Spectre.IO.Environment;
|
||||||
|
|
||||||
|
namespace Generator.Commands
|
||||||
|
{
|
||||||
|
public sealed class EmojiGeneratorCommand : AsyncCommand<GeneratorCommandSettings>
|
||||||
|
{
|
||||||
|
private readonly IFileSystem _fileSystem;
|
||||||
|
private readonly IEnvironment _environment;
|
||||||
|
private readonly IHtmlParser _parser;
|
||||||
|
|
||||||
|
private readonly Dictionary<string, string> _templates = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Templates/Emoji.Generated.template", "Emoji.Generated.cs" },
|
||||||
|
{ "Templates/Emoji.Json.template", "emojis.json" },
|
||||||
|
};
|
||||||
|
|
||||||
|
public EmojiGeneratorCommand()
|
||||||
|
{
|
||||||
|
_fileSystem = new FileSystem();
|
||||||
|
_environment = new SpectreEnvironment();
|
||||||
|
_parser = new HtmlParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<int> ExecuteAsync(CommandContext context, GeneratorCommandSettings settings)
|
||||||
|
{
|
||||||
|
var output = new DirectoryPath(settings.Output);
|
||||||
|
if (!_fileSystem.Directory.Exists(settings.Output))
|
||||||
|
{
|
||||||
|
_fileSystem.Directory.Create(settings.Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stream = await FetchEmojis(settings);
|
||||||
|
var document = await _parser.ParseDocumentAsync(stream);
|
||||||
|
var emojis = Emoji.Parse(document).OrderBy(x => x.Name)
|
||||||
|
.Where(emoji => !emoji.HasCombinators)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Render all templates
|
||||||
|
foreach (var (templateFilename, outputFilename) in _templates)
|
||||||
|
{
|
||||||
|
var result = await RenderTemplate(new FilePath(templateFilename), emojis);
|
||||||
|
|
||||||
|
var outputPath = output.CombineWithFilePath(outputFilename);
|
||||||
|
await File.WriteAllTextAsync(outputPath.FullPath, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Stream> FetchEmojis(GeneratorCommandSettings settings)
|
||||||
|
{
|
||||||
|
var input = string.IsNullOrEmpty(settings.Input)
|
||||||
|
? _environment.WorkingDirectory
|
||||||
|
: new DirectoryPath(settings.Input);
|
||||||
|
|
||||||
|
var file = _fileSystem.File.Retrieve(input.CombineWithFilePath("emoji-list.html"));
|
||||||
|
if (!file.Exists)
|
||||||
|
{
|
||||||
|
using var http = new HttpClient();
|
||||||
|
using var httpStream = await http.GetStreamAsync("http://www.unicode.org/emoji/charts/emoji-list.html");
|
||||||
|
using var outStream = file.OpenWrite();
|
||||||
|
|
||||||
|
await httpStream.CopyToAsync(outStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return file.OpenRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> RenderTemplate(Path path, IReadOnlyCollection<Emoji> emojis)
|
||||||
|
{
|
||||||
|
var text = await File.ReadAllTextAsync(path.FullPath);
|
||||||
|
|
||||||
|
var template = Template.Parse(text);
|
||||||
|
var templateContext = new TemplateContext
|
||||||
|
{
|
||||||
|
// Because of the insane amount of Emojis,
|
||||||
|
// we need to get rid of some secure defaults :P
|
||||||
|
LoopLimit = int.MaxValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
var scriptObject = new ScriptObject();
|
||||||
|
scriptObject.Import(new { Emojis = emojis });
|
||||||
|
templateContext.PushGlobal(scriptObject);
|
||||||
|
|
||||||
|
return await template.RenderAsync(templateContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,9 +24,17 @@
|
|||||||
<None Update="Templates\ColorPalette.Generated.template">
|
<None Update="Templates\ColorPalette.Generated.template">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Templates\Emoji.Json.template">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Templates\Emoji.Generated.template">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AngleSharp" Version="0.14.0" />
|
||||||
|
<PackageReference Include="Humanizer.Core" Version="2.8.26" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="Scriban" Version="2.1.3" />
|
<PackageReference Include="Scriban" Version="2.1.3" />
|
||||||
<PackageReference Include="Spectre.Cli" Version="0.36.1-preview.0.6" />
|
<PackageReference Include="Spectre.Cli" Version="0.36.1-preview.0.6" />
|
||||||
|
|||||||
95
resources/scripts/Generator/Models/Emoji.cs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using AngleSharp.Dom;
|
||||||
|
using AngleSharp.Html.Dom;
|
||||||
|
using Humanizer;
|
||||||
|
|
||||||
|
namespace Generator.Models
|
||||||
|
{
|
||||||
|
public class Emoji
|
||||||
|
{
|
||||||
|
private static readonly string[] _headers = { "count", "code", "sample", "name" };
|
||||||
|
|
||||||
|
private Emoji(string identifier, string name, string code, string description)
|
||||||
|
{
|
||||||
|
Identifier = identifier;
|
||||||
|
Name = name;
|
||||||
|
Code = code;
|
||||||
|
Description = description;
|
||||||
|
NormalizedCode = Code.Replace("\\U", "U+");
|
||||||
|
HasCombinators = Code.Split(new[] { "\\U" }, System.StringSplitOptions.RemoveEmptyEntries).Length > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
public string Code { get; }
|
||||||
|
public string NormalizedCode { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public bool HasCombinators { get; set; }
|
||||||
|
|
||||||
|
public static IEnumerable<Emoji> Parse(IHtmlDocument document)
|
||||||
|
{
|
||||||
|
var rows = document
|
||||||
|
.GetNodes<IHtmlTableRowElement>(predicate: row =>
|
||||||
|
row.Cells.Length >= _headers.Length && // Filter out rows that don't have enough cells.
|
||||||
|
row.Cells.All(x => x.LocalName == TagNames.Td)); // We're only interested in td cells, not th.
|
||||||
|
|
||||||
|
foreach (var row in rows)
|
||||||
|
{
|
||||||
|
var dictionary = _headers
|
||||||
|
.Zip(row.Cells, (header, cell) => (Header: header, cell.TextContent.Trim()))
|
||||||
|
.ToDictionary(x => x.Item1, x => x.Item2);
|
||||||
|
|
||||||
|
var code = TransformCode(dictionary["code"]);
|
||||||
|
var identifier = TransformName(dictionary["name"])
|
||||||
|
.Replace("-", "_")
|
||||||
|
.Replace("(", string.Empty)
|
||||||
|
.Replace(")", string.Empty);
|
||||||
|
|
||||||
|
var description = dictionary["name"].Humanize();
|
||||||
|
|
||||||
|
var name = identifier
|
||||||
|
.Replace("1st", "first")
|
||||||
|
.Replace("2nd", "second")
|
||||||
|
.Replace("3rd", "third")
|
||||||
|
.Pascalize();
|
||||||
|
|
||||||
|
yield return new Emoji(identifier, name, code, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string TransformName(string name)
|
||||||
|
{
|
||||||
|
return name.Replace(":", string.Empty)
|
||||||
|
.Replace(",", string.Empty)
|
||||||
|
.Replace(".", string.Empty)
|
||||||
|
.Replace("\u201c", string.Empty)
|
||||||
|
.Replace("\u201d", string.Empty)
|
||||||
|
.Replace("\u229b", string.Empty)
|
||||||
|
.Replace(' ', '_')
|
||||||
|
.Replace("’s", "s")
|
||||||
|
.Replace("’", "_")
|
||||||
|
.Replace("&", "and")
|
||||||
|
.Replace("#", "hash")
|
||||||
|
.Replace("*", "star")
|
||||||
|
.Replace("!", string.Empty)
|
||||||
|
.Trim()
|
||||||
|
.ToLowerInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string TransformCode(string code)
|
||||||
|
{
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (var part in code.Split(' '))
|
||||||
|
{
|
||||||
|
builder.Append(part.Length == 6
|
||||||
|
? part.Replace("+", "0000")
|
||||||
|
: part.Replace("+", "000"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString().Replace("U", "\\U");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ namespace Generator
|
|||||||
app.Configure(config =>
|
app.Configure(config =>
|
||||||
{
|
{
|
||||||
config.AddCommand<ColorGeneratorCommand>("colors");
|
config.AddCommand<ColorGeneratorCommand>("colors");
|
||||||
|
config.AddCommand<EmojiGeneratorCommand>("emoji");
|
||||||
});
|
});
|
||||||
|
|
||||||
return app.Run(args);
|
return app.Run(args);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
// Generated {{ date.now | date.to_string `%Y-%m-%d %k:%M` }}
|
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||||
//
|
//
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
// the code is regenerated.
|
// the code is regenerated.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
// Generated {{ date.now | date.to_string `%Y-%m-%d %k:%M` }}
|
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||||
//
|
//
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
// the code is regenerated.
|
// the code is regenerated.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
// Generated {{ date.now | date.to_string `%Y-%m-%d %k:%M` }}
|
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||||
//
|
//
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
// the code is regenerated.
|
// the code is regenerated.
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Spectre.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Utility for working with emojis.
|
||||||
|
/// </summary>
|
||||||
|
public static partial class Emoji
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, string> _emojis
|
||||||
|
= new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
|
||||||
|
{
|
||||||
|
{{~ for emoji in emojis ~}}
|
||||||
|
{ "{{ emoji.identifier }}", Emoji.Known.{{ emoji.name }} },
|
||||||
|
{{~ end ~}}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains all predefined emojis.
|
||||||
|
/// </summary>
|
||||||
|
public static class Known
|
||||||
|
{
|
||||||
|
{{- for emoji in emojis }}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the "{{ emoji.identifier }}" emoji.
|
||||||
|
/// Description: {{ emoji.description }}.
|
||||||
|
/// </summary>
|
||||||
|
public const string {{ emoji.name }} = "{{ emoji.code }}";
|
||||||
|
{{~ end ~}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
resources/scripts/Generator/Templates/Emoji.Json.template
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{{~ for x in 0..(emojis.size-1) ~}}
|
||||||
|
{
|
||||||
|
"id": "{{ emojis[x].identifier }}",
|
||||||
|
"name": "{{ emojis[x].name }}",
|
||||||
|
"description": "{{ emojis[x].description }}",
|
||||||
|
"code": "{{ emojis[x].normalized_code }}"
|
||||||
|
}{{ if x != (emojis.size-1) }},{{ end }}
|
||||||
|
{{~ end ~}}
|
||||||
|
]
|
||||||
@@ -86,4 +86,7 @@ dotnet_diagnostic.RCS1057.severity = none
|
|||||||
dotnet_diagnostic.RCS1227.severity = none
|
dotnet_diagnostic.RCS1227.severity = none
|
||||||
|
|
||||||
# IDE0004: Remove Unnecessary Cast
|
# IDE0004: Remove Unnecessary Cast
|
||||||
dotnet_diagnostic.IDE0004.severity = warning
|
dotnet_diagnostic.IDE0004.severity = warning
|
||||||
|
|
||||||
|
# CA1810: Initialize reference type static fields inline
|
||||||
|
dotnet_diagnostic.CA1810.severity = none
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup Label="Settings">
|
<PropertyGroup Label="Settings">
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
<LangVersion>8.0</LangVersion>
|
<LangVersion>9.0</LangVersion>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.113">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.113">
|
||||||
<PrivateAssets>All</PrivateAssets>
|
<PrivateAssets>All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Roslynator.Analyzers" Version="2.3.0">
|
<PackageReference Include="Roslynator.Analyzers" Version="3.0.0">
|
||||||
<PrivateAssets>All</PrivateAssets>
|
<PrivateAssets>All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -24,3 +24,6 @@ dotnet_diagnostic.CA2000.severity = none
|
|||||||
|
|
||||||
# SA1118: Parameter should not span multiple lines
|
# SA1118: Parameter should not span multiple lines
|
||||||
dotnet_diagnostic.SA1118.severity = none
|
dotnet_diagnostic.SA1118.severity = none
|
||||||
|
|
||||||
|
# CA1031: Do not catch general exception types
|
||||||
|
dotnet_diagnostic.CA1031.severity = none
|
||||||
|
|||||||
23
src/Spectre.Console.Tests/Data/Exceptions.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Spectre.Console.Tests.Data
|
||||||
|
{
|
||||||
|
public static class TestExceptions
|
||||||
|
{
|
||||||
|
[SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "<Pending>")]
|
||||||
|
public static bool MethodThatThrows(int? number) => throw new InvalidOperationException("Throwing!");
|
||||||
|
|
||||||
|
public static void ThrowWithInnerException()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MethodThatThrows(null);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Something threw!", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Spectre.Console.Tests
|
|
||||||
{
|
|
||||||
public static class ConsoleExtensions
|
|
||||||
{
|
|
||||||
public static void SetColor(this IAnsiConsole console, Color color, bool foreground)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foreground)
|
|
||||||
{
|
|
||||||
console.Foreground = color;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
console.Background = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,34 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Spectre.Console.Tests
|
namespace Spectre.Console.Tests
|
||||||
{
|
{
|
||||||
public static class StringExtensions
|
public static class StringExtensions
|
||||||
{
|
{
|
||||||
|
private static readonly Regex _lineNumberRegex = new Regex(":\\d+", RegexOptions.Singleline);
|
||||||
|
private static readonly Regex _filenameRegex = new Regex("\\sin\\s.*cs:nn", RegexOptions.Multiline);
|
||||||
|
|
||||||
public static string NormalizeLineEndings(this string text)
|
public static string NormalizeLineEndings(this string text)
|
||||||
{
|
{
|
||||||
return text?.Replace("\r\n", "\n", StringComparison.OrdinalIgnoreCase)
|
return text?.Replace("\r\n", "\n", StringComparison.OrdinalIgnoreCase)
|
||||||
?.Replace("\r", string.Empty, StringComparison.OrdinalIgnoreCase);
|
?.Replace("\r", string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string NormalizeStackTrace(this string text)
|
||||||
|
{
|
||||||
|
text = _lineNumberRegex.Replace(text, match =>
|
||||||
|
{
|
||||||
|
return ":nn";
|
||||||
|
});
|
||||||
|
|
||||||
|
return _filenameRegex.Replace(text, match =>
|
||||||
|
{
|
||||||
|
var value = match.Value;
|
||||||
|
var index = value.LastIndexOfAny(new[] { '\\', '/' });
|
||||||
|
var filename = value.Substring(index + 1, value.Length - index - 1);
|
||||||
|
|
||||||
|
return $" in /xyz/{filename}";
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/Spectre.Console.Tests/Extensions/StyleExtensions.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Spectre.Console.Tests
|
||||||
|
{
|
||||||
|
internal static class StyleExtensions
|
||||||
|
{
|
||||||
|
public static Style SetColor(this Style style, Color color, bool foreground)
|
||||||
|
{
|
||||||
|
if (foreground)
|
||||||
|
{
|
||||||
|
return style.Foreground(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return style.Background(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Spectre.Console.Tests
|
|
||||||
{
|
|
||||||
public sealed class AnsiConsoleFixture : IDisposable
|
|
||||||
{
|
|
||||||
private readonly StringWriter _writer;
|
|
||||||
|
|
||||||
public IAnsiConsole Console { get; }
|
|
||||||
|
|
||||||
public string Output => _writer.ToString();
|
|
||||||
|
|
||||||
public AnsiConsoleFixture(ColorSystem system, AnsiSupport ansi = AnsiSupport.Yes, int width = 80)
|
|
||||||
{
|
|
||||||
_writer = new StringWriter();
|
|
||||||
|
|
||||||
Console = new ConsoleWithWidth(
|
|
||||||
AnsiConsole.Create(new AnsiConsoleSettings
|
|
||||||
{
|
|
||||||
Ansi = ansi,
|
|
||||||
ColorSystem = (ColorSystemSupport)system,
|
|
||||||
Out = _writer,
|
|
||||||
}), width);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_writer?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Spectre.Console.Tests
|
|
||||||
{
|
|
||||||
public sealed class ConsoleWithWidth : IAnsiConsole
|
|
||||||
{
|
|
||||||
private readonly IAnsiConsole _console;
|
|
||||||
|
|
||||||
public Capabilities Capabilities => _console.Capabilities;
|
|
||||||
|
|
||||||
public int Width { get; }
|
|
||||||
public int Height => _console.Height;
|
|
||||||
|
|
||||||
public Encoding Encoding => _console.Encoding;
|
|
||||||
|
|
||||||
public Decoration Decoration { get => _console.Decoration; set => _console.Decoration = value; }
|
|
||||||
public Color Foreground { get => _console.Foreground; set => _console.Foreground = value; }
|
|
||||||
public Color Background { get => _console.Background; set => _console.Background = value; }
|
|
||||||
|
|
||||||
public ConsoleWithWidth(IAnsiConsole console, int width)
|
|
||||||
{
|
|
||||||
_console = console;
|
|
||||||
Width = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(string text)
|
|
||||||
{
|
|
||||||
_console.Write(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFrameworks>net5.0;netcoreapp3.1</TargetFrameworks>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
namespace Spectre.Console.Tests
|
namespace Spectre.Console.Tests
|
||||||
{
|
{
|
||||||
@@ -9,13 +11,18 @@ namespace Spectre.Console.Tests
|
|||||||
{
|
{
|
||||||
public Capabilities Capabilities { get; }
|
public Capabilities Capabilities { get; }
|
||||||
public Encoding Encoding { get; }
|
public Encoding Encoding { get; }
|
||||||
|
public IAnsiConsoleCursor Cursor => throw new NotSupportedException();
|
||||||
|
public TestableConsoleInput Input { get; }
|
||||||
|
|
||||||
public int Width { get; }
|
public int Width { get; }
|
||||||
public int Height { get; }
|
public int Height { get; }
|
||||||
|
|
||||||
|
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||||
|
|
||||||
public Decoration Decoration { get; set; }
|
public Decoration Decoration { get; set; }
|
||||||
public Color Foreground { get; set; }
|
public Color Foreground { get; set; }
|
||||||
public Color Background { get; set; }
|
public Color Background { get; set; }
|
||||||
|
public string Link { get; set; }
|
||||||
|
|
||||||
public StringWriter Writer { get; }
|
public StringWriter Writer { get; }
|
||||||
public string RawOutput => Writer.ToString();
|
public string RawOutput => Writer.ToString();
|
||||||
@@ -32,6 +39,7 @@ namespace Spectre.Console.Tests
|
|||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
Writer = new StringWriter();
|
Writer = new StringWriter();
|
||||||
|
Input = new TestableConsoleInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -39,9 +47,29 @@ namespace Spectre.Console.Tests
|
|||||||
Writer.Dispose();
|
Writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(string text)
|
public void Clear(bool home)
|
||||||
{
|
{
|
||||||
Writer.Write(text);
|
}
|
||||||
|
|
||||||
|
public void Write(Segment segment)
|
||||||
|
{
|
||||||
|
if (segment is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(segment));
|
||||||
|
}
|
||||||
|
|
||||||
|
Writer.Write(segment.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string[] WriteExceptionAndGetLines(Exception ex, ExceptionFormats formats = ExceptionFormats.Default)
|
||||||
|
{
|
||||||
|
this.WriteException(ex, formats);
|
||||||
|
|
||||||
|
return Output.NormalizeStackTrace()
|
||||||
|
.NormalizeLineEndings()
|
||||||
|
.Split(new char[] { '\n' })
|
||||||
|
.Select(line => line.TrimEnd())
|
||||||
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
10
src/Spectre.Console.Tests/Tools/TestLinkIdentityGenerator.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Spectre.Console.Tests.Tools
|
||||||
|
{
|
||||||
|
public sealed class TestLinkIdentityGenerator : ILinkIdentityGenerator
|
||||||
|
{
|
||||||
|
public int GenerateId(string link, string text)
|
||||||
|
{
|
||||||
|
return 1024;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/Spectre.Console.Tests/Tools/TestableAnsiConsole.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using Spectre.Console.Rendering;
|
||||||
|
using Spectre.Console.Tests.Tools;
|
||||||
|
|
||||||
|
namespace Spectre.Console.Tests
|
||||||
|
{
|
||||||
|
public sealed class TestableAnsiConsole : IDisposable, IAnsiConsole
|
||||||
|
{
|
||||||
|
private readonly StringWriter _writer;
|
||||||
|
private readonly IAnsiConsole _console;
|
||||||
|
|
||||||
|
public string Output => _writer.ToString();
|
||||||
|
|
||||||
|
public Capabilities Capabilities => _console.Capabilities;
|
||||||
|
public Encoding Encoding => _console.Encoding;
|
||||||
|
public int Width { get; }
|
||||||
|
public int Height => _console.Height;
|
||||||
|
public IAnsiConsoleCursor Cursor => _console.Cursor;
|
||||||
|
public TestableConsoleInput Input { get; }
|
||||||
|
|
||||||
|
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||||
|
|
||||||
|
public TestableAnsiConsole(ColorSystem system, AnsiSupport ansi = AnsiSupport.Yes, int width = 80)
|
||||||
|
{
|
||||||
|
_writer = new StringWriter();
|
||||||
|
_console = AnsiConsole.Create(new AnsiConsoleSettings
|
||||||
|
{
|
||||||
|
Ansi = ansi,
|
||||||
|
ColorSystem = (ColorSystemSupport)system,
|
||||||
|
Out = _writer,
|
||||||
|
LinkIdentityGenerator = new TestLinkIdentityGenerator(),
|
||||||
|
});
|
||||||
|
|
||||||
|
Width = width;
|
||||||
|
Input = new TestableConsoleInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_writer?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear(bool home)
|
||||||
|
{
|
||||||
|
_console.Clear(home);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(Segment segment)
|
||||||
|
{
|
||||||
|
_console.Write(segment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||