mirror of
https://github.com/spectreconsole/spectre.console.git
synced 2025-10-25 15:19:23 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3847a8949f | ||
|
|
eeb3f967b6 | ||
|
|
090b30f731 | ||
|
|
df291ef84e | ||
|
|
7d6104ace4 | ||
|
|
314456ca17 | ||
|
|
b7f654cd7f | ||
|
|
fea8a36e8a | ||
|
|
0632b38477 | ||
|
|
a7b7d4e556 | ||
|
|
11d331e31d | ||
|
|
ce670a7ca9 | ||
|
|
101e244059 | ||
|
|
504746c5dc |
1
.github/workflows/ci.yaml
vendored
1
.github/workflows/ci.yaml
vendored
@@ -69,6 +69,7 @@ jobs:
|
|||||||
dotnet example grid
|
dotnet example grid
|
||||||
dotnet example panel
|
dotnet example panel
|
||||||
dotnet example colors
|
dotnet example colors
|
||||||
|
dotnet example emojis
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
|||||||
[Pp]ackages/
|
[Pp]ackages/
|
||||||
/.artifacts/
|
/.artifacts/
|
||||||
/[Tt]ools/
|
/[Tt]ools/
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
# Cakeup
|
# Cakeup
|
||||||
cakeup-x86_64-latest.exe
|
cakeup-x86_64-latest.exe
|
||||||
|
|||||||
@@ -22,11 +22,23 @@
|
|||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="src\Data\emojis.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="src\Data\emojis.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.5" />
|
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.5" />
|
||||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.0" />
|
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="input\assets\images\emojis\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="Versioning" BeforeTargets="MinVer">
|
<Target Name="Versioning" BeforeTargets="MinVer">
|
||||||
<PropertyGroup Label="Build">
|
<PropertyGroup Label="Build">
|
||||||
<MinVerDefaultPreReleasePhase>preview</MinVerDefaultPreReleasePhase>
|
<MinVerDefaultPreReleasePhase>preview</MinVerDefaultPreReleasePhase>
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -128,14 +128,28 @@
|
|||||||
{
|
{
|
||||||
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)">
|
||||||
|
@if(root.ShowLink())
|
||||||
|
{
|
||||||
@Html.DocumentLink(root)
|
@Html.DocumentLink(root)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@root.GetTitle()
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
|
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
|
||||||
{
|
{
|
||||||
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)">
|
||||||
|
@if(document.ShowLink())
|
||||||
|
{
|
||||||
@Html.DocumentLink(document)
|
@Html.DocumentLink(document)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@document.GetTitle()
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (documentChildren.OnlyVisible().Any())
|
@if (documentChildren.OnlyVisible().Any())
|
||||||
|
|||||||
38
docs/input/appendix/emojis.md
Normal file
38
docs/input/appendix/emojis.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
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);
|
||||||
|
```
|
||||||
|
|
||||||
|
# Emojis
|
||||||
|
|
||||||
|
_The images in the table below might not render correctly in your
|
||||||
|
browser for the same reasons mentioned in the `Compatibility` section._
|
||||||
|
|
||||||
|
<?# EmojiTable /?>
|
||||||
@@ -1,3 +1,10 @@
|
|||||||
Title: Appendix
|
Title: Appendix
|
||||||
Order: 10
|
Order: 10
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# Sections
|
||||||
|
|
||||||
|
* [Styles](xref:styles)
|
||||||
|
* [Colors](xref:colors)
|
||||||
|
* [Borders](xref:borders)
|
||||||
|
* [Emojis](xref:emojis)
|
||||||
@@ -2,8 +2,7 @@ Title: Markup
|
|||||||
Order: 2
|
Order: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
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
|
# Syntax
|
||||||
|
|
||||||
@@ -54,6 +53,16 @@ You can set the background color in markup by prefixing the color with
|
|||||||
[default on blue]World[/]
|
[default on blue]World[/]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Rendering emojis
|
||||||
|
|
||||||
|
To output an emoji as part of markup, you can use emoji shortcodes.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
|
||||||
|
```
|
||||||
|
|
||||||
|
For a list of emoji, see the [Emojis](xref:styles) appendix section.
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
|
|
||||||
For a list of colors, see the [Colors](xref:colors) appendix section.
|
For a list of colors, see the [Colors](xref:colors) appendix section.
|
||||||
|
|||||||
@@ -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
7946
docs/src/Data/emojis.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
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
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,13 +26,8 @@ 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
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,11 +17,10 @@ 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;
|
||||||
|
|
||||||
|
// Headers
|
||||||
var table = new XElement("table", new XAttribute("class", "table"));
|
var table = new XElement("table", new XAttribute("class", "table"));
|
||||||
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", ""));
|
||||||
|
|||||||
45
docs/src/Shortcodes/EmojiTableShortcode.cs
Normal file
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"));
|
||||||
|
var header = new XElement("tr", new XAttribute("class", "emoji-row"));
|
||||||
|
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 = string.Format("&#x{0};", emoji.Code.Replace("U+", string.Empty));
|
||||||
|
|
||||||
|
var row = new XElement("tr");
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
using Spectre.Console.Rendering;
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
|
|||||||
14
examples/Emojis/Emojis.csproj
Normal file
14
examples/Emojis/Emojis.csproj
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<Description>Demonstrates how to render emojis.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
17
examples/Emojis/Program.cs
Normal file
17
examples/Emojis/Program.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace Emojis
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
// Markup
|
||||||
|
AnsiConsole.Render(
|
||||||
|
new Panel("[yellow]Hello :globe_showing_europe_africa:![/]")
|
||||||
|
.RoundedBorder()
|
||||||
|
.SetHeader("Markup"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,15 +9,19 @@ namespace Info
|
|||||||
var grid = new Grid()
|
var grid = new Grid()
|
||||||
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
||||||
.AddColumn()
|
.AddColumn()
|
||||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
.AddRow("[b]:artist_palette: Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
||||||
.AddRow("[b]Supports ansi?[/]", $"{AnsiConsole.Capabilities.SupportsAnsi}")
|
.AddRow("[b]:nail_polish: Supports ansi?[/]", $"{GetEmoji(AnsiConsole.Capabilities.SupportsAnsi)}")
|
||||||
.AddRow("[b]Legacy console?[/]", $"{AnsiConsole.Capabilities.LegacyConsole}")
|
.AddRow("[b]:top_hat: Legacy console?[/]", $"{GetEmoji(AnsiConsole.Capabilities.LegacyConsole)}")
|
||||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
.AddRow("[b]:left_right_arrow: Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
||||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
.AddRow("[b]:up_down_arrow: Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
||||||
|
|
||||||
AnsiConsole.Render(
|
AnsiConsole.Render(
|
||||||
new Panel(grid)
|
new Panel(grid)
|
||||||
.SetHeader("Information"));
|
.SetHeader("Information"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetEmoji(bool value) => value
|
||||||
|
? ":thumbs_up:"
|
||||||
|
: ":thumbs_down:";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
examples/Links/Links.csproj
Normal file
14
examples/Links/Links.csproj
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<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
21
examples/Links/Program.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace Links
|
||||||
|
{
|
||||||
|
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]┻━┻[/]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
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
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
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
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 ~}}
|
||||||
|
]
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
15
src/Spectre.Console.Tests/Extensions/StyleExtensions.cs
Normal file
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.WithForeground(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return style.WithBackground(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
44
src/Spectre.Console.Tests/Tools/AnsiConsoleFixture.cs
Normal file
44
src/Spectre.Console.Tests/Tools/AnsiConsoleFixture.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_writer?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(string text, Style style)
|
||||||
|
{
|
||||||
|
_console.Write(text, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ namespace Spectre.Console.Tests
|
|||||||
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();
|
||||||
@@ -39,7 +40,7 @@ namespace Spectre.Console.Tests
|
|||||||
Writer.Dispose();
|
Writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(string text)
|
public void Write(string text, Style style)
|
||||||
{
|
{
|
||||||
Writer.Write(text);
|
Writer.Write(text);
|
||||||
}
|
}
|
||||||
10
src/Spectre.Console.Tests/Tools/TestLinkIdentityGenerator.cs
Normal file
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,14 +13,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Return_Correct_Code(bool foreground, string expected)
|
public void Should_Return_Correct_Code(bool foreground, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
|
var console = new TestableAnsiConsole(ColorSystem.TrueColor);
|
||||||
fixture.Console.SetColor(new Color(128, 0, 128), foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(new Color(128, 0, 128), foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -29,14 +28,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Return_Eight_Bit_Ansi_Code_For_Known_Colors(bool foreground, string expected)
|
public void Should_Return_Eight_Bit_Ansi_Code_For_Known_Colors(bool foreground, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
|
var console = new TestableAnsiConsole(ColorSystem.TrueColor);
|
||||||
fixture.Console.SetColor(Color.Purple, foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(Color.Purple, foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,14 +46,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected)
|
public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.EightBit);
|
var console = new TestableAnsiConsole(ColorSystem.EightBit);
|
||||||
fixture.Console.SetColor(Color.Olive, foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(Color.Olive, foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -64,14 +61,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Map_TrueColor_To_Nearest_Eight_Bit_Color_If_Possible(bool foreground, string expected)
|
public void Should_Map_TrueColor_To_Nearest_Eight_Bit_Color_If_Possible(bool foreground, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.EightBit);
|
var console = new TestableAnsiConsole(ColorSystem.EightBit);
|
||||||
fixture.Console.SetColor(new Color(128, 128, 0), foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(new Color(128, 128, 0), foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -80,14 +76,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Estimate_TrueColor_To_Nearest_Eight_Bit_Color(bool foreground, string expected)
|
public void Should_Estimate_TrueColor_To_Nearest_Eight_Bit_Color(bool foreground, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.EightBit);
|
var console = new TestableAnsiConsole(ColorSystem.EightBit);
|
||||||
fixture.Console.SetColor(new Color(126, 127, 0), foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(new Color(126, 127, 0), foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,14 +94,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected)
|
public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
|
var console = new TestableAnsiConsole(ColorSystem.Standard);
|
||||||
fixture.Console.SetColor(Color.Olive, foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(Color.Olive, foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -120,14 +114,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
string expected)
|
string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
|
var console = new TestableAnsiConsole(ColorSystem.Standard);
|
||||||
fixture.Console.SetColor(new Color(r, g, b), foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -141,14 +134,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
string expected)
|
string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
|
var console = new TestableAnsiConsole(ColorSystem.Standard);
|
||||||
fixture.Console.SetColor(new Color(r, g, b), foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,14 +152,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected)
|
public void Should_Return_Correct_Code_For_Known_Color(bool foreground, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Legacy);
|
var console = new TestableAnsiConsole(ColorSystem.Legacy);
|
||||||
fixture.Console.SetColor(Color.Olive, foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(Color.Olive, foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -181,14 +172,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
string expected)
|
string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Legacy);
|
var console = new TestableAnsiConsole(ColorSystem.Legacy);
|
||||||
fixture.Console.SetColor(new Color(r, g, b), foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -202,14 +192,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
string expected)
|
string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Legacy);
|
var console = new TestableAnsiConsole(ColorSystem.Legacy);
|
||||||
fixture.Console.SetColor(new Color(r, g, b), foreground);
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write("Hello", new Style().SetColor(new Color(r, g, b), foreground));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,18 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("[yellow]Hello[/]", "[93mHello[0m")]
|
[InlineData("[yellow]Hello[/]", "[93mHello[0m")]
|
||||||
[InlineData("[yellow]Hello [italic]World[/]![/]", "[93mHello [0m[3;93mWorld[0m[93m![0m")]
|
[InlineData("[yellow]Hello [italic]World[/]![/]", "[93mHello [0m[3;93mWorld[0m[93m![0m")]
|
||||||
|
[InlineData("[link=https://patriksvensson.se]Click to visit my blog[/]", "]8;id=1024;https://patriksvensson.se\\Click to visit my blog]8;;\\")]
|
||||||
|
[InlineData("[link]https://patriksvensson.se[/]", "]8;id=1024;https://patriksvensson.se\\https://patriksvensson.se]8;;\\")]
|
||||||
public void Should_Output_Expected_Ansi_For_Markup(string markup, string expected)
|
public void Should_Output_Expected_Ansi_For_Markup(string markup, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Markup(markup);
|
console.Markup(markup);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -30,13 +32,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Be_Able_To_Escape_Tags(string markup, string expected)
|
public void Should_Be_Able_To_Escape_Tags(string markup, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Markup(markup);
|
console.Markup(markup);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -47,10 +49,10 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Throw_If_Encounters_Malformed_Tag(string markup, string expected)
|
public void Should_Throw_If_Encounters_Malformed_Tag(string markup, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var result = Record.Exception(() => fixture.Console.Markup(markup));
|
var result = Record.Exception(() => console.Markup(markup));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
result.ShouldBeOfType<InvalidOperationException>()
|
result.ShouldBeOfType<InvalidOperationException>()
|
||||||
@@ -61,10 +63,10 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Throw_If_Tags_Are_Unbalanced()
|
public void Should_Throw_If_Tags_Are_Unbalanced()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var result = Record.Exception(() => fixture.Console.Markup("[yellow][blue]Hello[/]"));
|
var result = Record.Exception(() => console.Markup("[yellow][blue]Hello[/]"));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
result.ShouldBeOfType<InvalidOperationException>()
|
result.ShouldBeOfType<InvalidOperationException>()
|
||||||
@@ -75,10 +77,10 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Throw_If_Encounters_Closing_Tag()
|
public void Should_Throw_If_Encounters_Closing_Tag()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var result = Record.Exception(() => fixture.Console.Markup("Hello[/]World"));
|
var result = Record.Exception(() => console.Markup("Hello[/]World"));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
result.ShouldBeOfType<InvalidOperationException>()
|
result.ShouldBeOfType<InvalidOperationException>()
|
||||||
|
|||||||
@@ -18,14 +18,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Write_Decorated_Text_Correctly(Decoration decoration, string expected)
|
public void Should_Write_Decorated_Text_Correctly(Decoration decoration, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
|
var console = new TestableAnsiConsole(ColorSystem.TrueColor);
|
||||||
fixture.Console.Decoration = decoration;
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello World");
|
console.Write("Hello World", Style.WithDecoration(decoration));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -34,14 +33,13 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Write_Text_With_Multiple_Decorations_Correctly(Decoration decoration, string expected)
|
public void Should_Write_Text_With_Multiple_Decorations_Correctly(Decoration decoration, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.TrueColor);
|
var console = new TestableAnsiConsole(ColorSystem.TrueColor);
|
||||||
fixture.Console.Decoration = decoration;
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello World");
|
console.Write("Hello World", Style.WithDecoration(decoration));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe(expected);
|
console.Output.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@@ -11,237 +10,68 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Combine_Decoration_And_Colors()
|
public void Should_Combine_Decoration_And_Colors()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
|
var console = new TestableAnsiConsole(ColorSystem.Standard);
|
||||||
fixture.Console.Foreground = Color.RoyalBlue1;
|
|
||||||
fixture.Console.Background = Color.NavajoWhite1;
|
|
||||||
fixture.Console.Decoration = Decoration.Italic;
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write(
|
||||||
|
"Hello",
|
||||||
|
Style.WithForeground(Color.RoyalBlue1)
|
||||||
|
.WithBackground(Color.NavajoWhite1)
|
||||||
|
.WithDecoration(Decoration.Italic));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe("\u001b[3;90;47mHello\u001b[0m");
|
console.Output.ShouldBe("\u001b[3;90;47mHello\u001b[0m");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Should_Not_Include_Foreground_If_Set_To_Default_Color()
|
public void Should_Not_Include_Foreground_If_Set_To_Default_Color()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
|
var console = new TestableAnsiConsole(ColorSystem.Standard);
|
||||||
fixture.Console.Foreground = Color.Default;
|
|
||||||
fixture.Console.Background = Color.NavajoWhite1;
|
|
||||||
fixture.Console.Decoration = Decoration.Italic;
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write(
|
||||||
|
"Hello",
|
||||||
|
Style.WithForeground(Color.Default)
|
||||||
|
.WithBackground(Color.NavajoWhite1)
|
||||||
|
.WithDecoration(Decoration.Italic));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe("\u001b[3;47mHello\u001b[0m");
|
console.Output.ShouldBe("\u001b[3;47mHello\u001b[0m");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Should_Not_Include_Background_If_Set_To_Default_Color()
|
public void Should_Not_Include_Background_If_Set_To_Default_Color()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
|
var console = new TestableAnsiConsole(ColorSystem.Standard);
|
||||||
fixture.Console.Foreground = Color.RoyalBlue1;
|
|
||||||
fixture.Console.Background = Color.Default;
|
|
||||||
fixture.Console.Decoration = Decoration.Italic;
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write(
|
||||||
|
"Hello",
|
||||||
|
Style.WithForeground(Color.RoyalBlue1)
|
||||||
|
.WithBackground(Color.Default)
|
||||||
|
.WithDecoration(Decoration.Italic));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe("\u001b[3;90mHello\u001b[0m");
|
console.Output.ShouldBe("\u001b[3;90mHello\u001b[0m");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Should_Not_Include_Decoration_If_Set_To_None()
|
public void Should_Not_Include_Decoration_If_Set_To_None()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard);
|
var console = new TestableAnsiConsole(ColorSystem.Standard);
|
||||||
fixture.Console.Foreground = Color.RoyalBlue1;
|
|
||||||
fixture.Console.Background = Color.NavajoWhite1;
|
|
||||||
fixture.Console.Decoration = Decoration.None;
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Write("Hello");
|
console.Write(
|
||||||
|
"Hello",
|
||||||
|
Style.WithForeground(Color.RoyalBlue1)
|
||||||
|
.WithBackground(Color.NavajoWhite1)
|
||||||
|
.WithDecoration(Decoration.None));
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe("\u001b[90;47mHello\u001b[0m");
|
console.Output.ShouldBe("\u001b[90;47mHello\u001b[0m");
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class Write
|
|
||||||
{
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Int32_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, 32);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_UInt32_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, 32U);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Int64_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, 32L);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_UInt64_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, 32UL);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Single_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, 32.432F);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32.432");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Double_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, (double)32.432);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32.432");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Decimal_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, 32.432M);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32.432");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Boolean_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, true);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("True");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Char_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(CultureInfo.InvariantCulture, 'P');
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("P");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Char_Array_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
new[] { 'P', 'a', 't', 'r', 'i', 'k' });
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("Patrik");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Formatted_String_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.Write(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
"Hello {0}! {1}",
|
|
||||||
"World", 32);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("Hello World! 32");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class WriteLine
|
public sealed class WriteLine
|
||||||
@@ -250,16 +80,14 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Reset_Colors_Correctly_After_Line_Break()
|
public void Should_Reset_Colors_Correctly_After_Line_Break()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Background = ConsoleColor.Red;
|
console.WriteLine("Hello", Style.WithBackground(ConsoleColor.Red));
|
||||||
fixture.Console.WriteLine("Hello");
|
console.WriteLine("World", Style.WithBackground(ConsoleColor.Green));
|
||||||
fixture.Console.Background = ConsoleColor.Green;
|
|
||||||
fixture.Console.WriteLine("World");
|
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.NormalizeLineEndings()
|
console.Output.NormalizeLineEndings()
|
||||||
.ShouldBe("[101mHello[0m\n[102mWorld[0m\n");
|
.ShouldBe("[101mHello[0m\n[102mWorld[0m\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,186 +95,15 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Reset_Colors_Correctly_After_Line_Break_In_Text()
|
public void Should_Reset_Colors_Correctly_After_Line_Break_In_Text()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, AnsiSupport.Yes);
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Console.Background = ConsoleColor.Red;
|
console.WriteLine("Hello\nWorld", Style.WithBackground(ConsoleColor.Red));
|
||||||
fixture.Console.WriteLine("Hello\nWorld");
|
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.NormalizeLineEndings()
|
console.Output.NormalizeLineEndings()
|
||||||
.ShouldBe("[101mHello[0m\n[101mWorld[0m\n");
|
.ShouldBe("[101mHello[0m\n[101mWorld[0m\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Int32_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_UInt32_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32U);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Int64_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32L);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_UInt64_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32UL);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Single_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32.432F);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32.432" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Double_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, (double)32.432);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32.432" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Decimal_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, 32.432M);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("32.432" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Boolean_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, true);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("True" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Char_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(CultureInfo.InvariantCulture, 'P');
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("P" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Char_Array_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
new[] { 'P', 'a', 't', 'r', 'i', 'k' });
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("Patrik" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(AnsiSupport.Yes)]
|
|
||||||
[InlineData(AnsiSupport.No)]
|
|
||||||
public void Should_Write_Formatted_String_With_Format_Provider(AnsiSupport ansi)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
var fixture = new AnsiConsoleFixture(ColorSystem.Standard, ansi);
|
|
||||||
|
|
||||||
// When
|
|
||||||
fixture.Console.WriteLine(
|
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
"Hello {0}! {1}",
|
|
||||||
"World", 32);
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fixture.Output.ShouldBe("Hello World! 32" + Environment.NewLine);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/Spectre.Console.Tests/Unit/EmojiTests.cs
Normal file
44
src/Spectre.Console.Tests/Unit/EmojiTests.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using Shouldly;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Spectre.Console.Tests.Unit
|
||||||
|
{
|
||||||
|
public sealed class EmojiTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Should_Substitute_Emoji_Shortcodes_In_Markdown()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new TestableAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Markup("Hello :globe_showing_europe_africa:!");
|
||||||
|
|
||||||
|
// Then
|
||||||
|
console.Output.ShouldBe("Hello 🌍!");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Contain_Predefined_Emojis()
|
||||||
|
{
|
||||||
|
// Given, When
|
||||||
|
const string result = "Hello " + Emoji.Known.GlobeShowingEuropeAfrica + "!";
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBe("Hello 🌍!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class TheReplaceMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Should_Replace_Emojis_In_Text()
|
||||||
|
{
|
||||||
|
// Given, When
|
||||||
|
var result = Emoji.Replace("Hello :globe_showing_europe_africa:!");
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBe("Hello 🌍!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -190,9 +190,9 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
// Given
|
// Given
|
||||||
var console = new PlainConsole(width: 80);
|
var console = new PlainConsole(width: 80);
|
||||||
var grid = new Grid();
|
var grid = new Grid();
|
||||||
grid.AddColumn(new GridColumn { Padding = new Padding(3, 0) });
|
grid.AddColumn(new GridColumn { Padding = new Padding(3, 0, 0, 0) });
|
||||||
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0) });
|
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0, 0, 0) });
|
||||||
grid.AddColumn(new GridColumn { Padding = new Padding(0, 3) });
|
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0, 3, 0) });
|
||||||
grid.AddRow("Foo", "Bar", "Baz");
|
grid.AddRow("Foo", "Bar", "Baz");
|
||||||
grid.AddRow("Qux", "Corgi", "Waldo");
|
grid.AddRow("Qux", "Corgi", "Waldo");
|
||||||
grid.AddRow("Grault", "Garply", "Fred");
|
grid.AddRow("Grault", "Garply", "Fred");
|
||||||
@@ -213,7 +213,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
var console = new PlainConsole(width: 80);
|
var console = new PlainConsole(width: 80);
|
||||||
var grid = new Grid();
|
var grid = new Grid();
|
||||||
grid.AddColumn(new GridColumn { NoWrap = true });
|
grid.AddColumn(new GridColumn { NoWrap = true });
|
||||||
grid.AddColumn(new GridColumn { Padding = new Padding(2, 0) });
|
grid.AddColumn(new GridColumn { Padding = new Padding(2, 0, 0, 0) });
|
||||||
grid.AddRow("[bold]Options[/]", string.Empty);
|
grid.AddRow("[bold]Options[/]", string.Empty);
|
||||||
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[/]", "The configuration to run for.\nThe default for most projects is [green]Debug[/].");
|
grid.AddRow(" [blue]-c[/], [blue]--configuration[/]", "The configuration to run for.\nThe default for most projects is [green]Debug[/].");
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Throw_If_Closing_Tag_Is_Not_Properly_Escaped(string input)
|
public void Should_Throw_If_Closing_Tag_Is_Not_Properly_Escaped(string input)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new PlainConsole();
|
var console = new PlainConsole();
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var result = Record.Exception(() => new Markup(input));
|
var result = Record.Exception(() => new Markup(input));
|
||||||
@@ -27,14 +27,30 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Escape_Markup_Blocks_As_Expected()
|
public void Should_Escape_Markup_Blocks_As_Expected()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new PlainConsole();
|
var console = new PlainConsole();
|
||||||
var markup = new Markup("Hello [[ World ]] !");
|
var markup = new Markup("Hello [[ World ]] !");
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Render(markup);
|
console.Render(markup);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output.ShouldBe("Hello [ World ] !");
|
console.Output.ShouldBe("Hello [ World ] !");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("Hello [link=http://example.com]example.com[/]", "Hello example.com")]
|
||||||
|
[InlineData("Hello [link=http://example.com]http://example.com[/]", "Hello http://example.com")]
|
||||||
|
public void Should_Render_Links_As_Expected(string input, string output)
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new PlainConsole();
|
||||||
|
var markup = new Markup(input);
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Render(markup);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
console.Output.ShouldBe(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
107
src/Spectre.Console.Tests/Unit/PadderTests.cs
Normal file
107
src/Spectre.Console.Tests/Unit/PadderTests.cs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
using Shouldly;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Spectre.Console.Tests.Unit
|
||||||
|
{
|
||||||
|
public sealed class PadderTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Should_Render_Padded_Object_Correctly()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new PlainConsole(width: 60);
|
||||||
|
var table = new Table();
|
||||||
|
table.AddColumn("Foo");
|
||||||
|
table.AddColumn("Bar");
|
||||||
|
table.AddRow("Baz", "Qux");
|
||||||
|
table.AddRow("Corgi", "Waldo");
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Render(new Padder(table).SetPadding(1, 2, 3, 4));
|
||||||
|
|
||||||
|
// Then
|
||||||
|
console.Lines.Count.ShouldBe(12);
|
||||||
|
console.Lines[00].ShouldBe(" ");
|
||||||
|
console.Lines[01].ShouldBe(" ");
|
||||||
|
console.Lines[02].ShouldBe(" ┌───────┬───────┐ ");
|
||||||
|
console.Lines[03].ShouldBe(" │ Foo │ Bar │ ");
|
||||||
|
console.Lines[04].ShouldBe(" ├───────┼───────┤ ");
|
||||||
|
console.Lines[05].ShouldBe(" │ Baz │ Qux │ ");
|
||||||
|
console.Lines[06].ShouldBe(" │ Corgi │ Waldo │ ");
|
||||||
|
console.Lines[07].ShouldBe(" └───────┴───────┘ ");
|
||||||
|
console.Lines[08].ShouldBe(" ");
|
||||||
|
console.Lines[09].ShouldBe(" ");
|
||||||
|
console.Lines[10].ShouldBe(" ");
|
||||||
|
console.Lines[11].ShouldBe(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Render_Expanded_Padded_Object_Correctly()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new PlainConsole(width: 60);
|
||||||
|
var table = new Table();
|
||||||
|
table.AddColumn("Foo");
|
||||||
|
table.AddColumn("Bar");
|
||||||
|
table.AddRow("Baz", "Qux");
|
||||||
|
table.AddRow("Corgi", "Waldo");
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Render(new Padder(table)
|
||||||
|
.SetPadding(1, 2, 3, 4)
|
||||||
|
.Expand());
|
||||||
|
|
||||||
|
// Then
|
||||||
|
console.Lines.Count.ShouldBe(12);
|
||||||
|
console.Lines[00].ShouldBe(" ");
|
||||||
|
console.Lines[01].ShouldBe(" ");
|
||||||
|
console.Lines[02].ShouldBe(" ┌───────┬───────┐ ");
|
||||||
|
console.Lines[03].ShouldBe(" │ Foo │ Bar │ ");
|
||||||
|
console.Lines[04].ShouldBe(" ├───────┼───────┤ ");
|
||||||
|
console.Lines[05].ShouldBe(" │ Baz │ Qux │ ");
|
||||||
|
console.Lines[06].ShouldBe(" │ Corgi │ Waldo │ ");
|
||||||
|
console.Lines[07].ShouldBe(" └───────┴───────┘ ");
|
||||||
|
console.Lines[08].ShouldBe(" ");
|
||||||
|
console.Lines[09].ShouldBe(" ");
|
||||||
|
console.Lines[10].ShouldBe(" ");
|
||||||
|
console.Lines[11].ShouldBe(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Render_Padded_Object_Correctly_When_Nested_Within_Other_Object()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new PlainConsole(width: 60);
|
||||||
|
var table = new Table();
|
||||||
|
table.AddColumn("Foo");
|
||||||
|
table.AddColumn("Bar", c => c.PadLeft(0).PadRight(0));
|
||||||
|
table.AddRow("Baz", "Qux");
|
||||||
|
table.AddRow(new Text("Corgi"), new Padder(new Panel("Waldo"))
|
||||||
|
.SetPadding(2, 1, 2, 1));
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Render(new Padder(table)
|
||||||
|
.SetPadding(1, 2, 3, 4)
|
||||||
|
.Expand());
|
||||||
|
|
||||||
|
// Then
|
||||||
|
console.Lines.Count.ShouldBe(16);
|
||||||
|
console.Lines[00].ShouldBe(" ");
|
||||||
|
console.Lines[01].ShouldBe(" ");
|
||||||
|
console.Lines[02].ShouldBe(" ┌───────┬─────────────┐ ");
|
||||||
|
console.Lines[03].ShouldBe(" │ Foo │Bar │ ");
|
||||||
|
console.Lines[04].ShouldBe(" ├───────┼─────────────┤ ");
|
||||||
|
console.Lines[05].ShouldBe(" │ Baz │Qux │ ");
|
||||||
|
console.Lines[06].ShouldBe(" │ Corgi │ │ ");
|
||||||
|
console.Lines[07].ShouldBe(" │ │ ┌───────┐ │ ");
|
||||||
|
console.Lines[08].ShouldBe(" │ │ │ Waldo │ │ ");
|
||||||
|
console.Lines[09].ShouldBe(" │ │ └───────┘ │ ");
|
||||||
|
console.Lines[10].ShouldBe(" │ │ │ ");
|
||||||
|
console.Lines[11].ShouldBe(" └───────┴─────────────┘ ");
|
||||||
|
console.Lines[12].ShouldBe(" ");
|
||||||
|
console.Lines[13].ShouldBe(" ");
|
||||||
|
console.Lines[14].ShouldBe(" ");
|
||||||
|
console.Lines[15].ShouldBe(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,25 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
console.Lines[2].ShouldBe("└─────────────┘");
|
console.Lines[2].ShouldBe("└─────────────┘");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Render_Panel_With_Padding_Set_To_Zero()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var console = new PlainConsole(width: 80);
|
||||||
|
|
||||||
|
// When
|
||||||
|
console.Render(new Panel(new Text("Hello World"))
|
||||||
|
{
|
||||||
|
Padding = new Padding(0, 0, 0, 0),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then
|
||||||
|
console.Lines.Count.ShouldBe(3);
|
||||||
|
console.Lines[0].ShouldBe("┌───────────┐");
|
||||||
|
console.Lines[1].ShouldBe("│Hello World│");
|
||||||
|
console.Lines[2].ShouldBe("└───────────┘");
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Should_Render_Panel_With_Padding()
|
public void Should_Render_Panel_With_Padding()
|
||||||
{
|
{
|
||||||
@@ -30,14 +49,17 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
// When
|
// When
|
||||||
console.Render(new Panel(new Text("Hello World"))
|
console.Render(new Panel(new Text("Hello World"))
|
||||||
{
|
{
|
||||||
Padding = new Padding(3, 5),
|
Padding = new Padding(3, 1, 5, 2),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
console.Lines.Count.ShouldBe(3);
|
console.Lines.Count.ShouldBe(6);
|
||||||
console.Lines[0].ShouldBe("┌───────────────────┐");
|
console.Lines[0].ShouldBe("┌───────────────────┐");
|
||||||
console.Lines[1].ShouldBe("│ Hello World │");
|
console.Lines[1].ShouldBe("│ │");
|
||||||
console.Lines[2].ShouldBe("└───────────────────┘");
|
console.Lines[2].ShouldBe("│ Hello World │");
|
||||||
|
console.Lines[3].ShouldBe("│ │");
|
||||||
|
console.Lines[4].ShouldBe("│ │");
|
||||||
|
console.Lines[5].ShouldBe("└───────────────────┘");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -51,7 +73,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
{
|
{
|
||||||
Header = new PanelHeader("Greeting"),
|
Header = new PanelHeader("Greeting"),
|
||||||
Expand = true,
|
Expand = true,
|
||||||
Padding = new Padding(2, 2),
|
Padding = new Padding(2, 0, 2, 0),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic);
|
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic);
|
||||||
var other = new Style(Color.Green, Color.Silver, Decoration.Underline);
|
var other = new Style(Color.Green, Color.Silver, Decoration.Underline, "https://example.com");
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var result = first.Combine(other);
|
var result = first.Combine(other);
|
||||||
@@ -20,6 +20,77 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
result.Foreground.ShouldBe(Color.Green);
|
result.Foreground.ShouldBe(Color.Green);
|
||||||
result.Background.ShouldBe(Color.Silver);
|
result.Background.ShouldBe(Color.Silver);
|
||||||
result.Decoration.ShouldBe(Decoration.Bold | Decoration.Italic | Decoration.Underline);
|
result.Decoration.ShouldBe(Decoration.Bold | Decoration.Italic | Decoration.Underline);
|
||||||
|
result.Link.ShouldBe("https://example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Consider_Two_Identical_Styles_Equal()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
var second = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = first.Equals(second);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Not_Consider_Two_Styles_With_Different_Foreground_Colors_Equal()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
var second = new Style(Color.Blue, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = first.Equals(second);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Not_Consider_Two_Styles_With_Different_Background_Colors_Equal()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
var second = new Style(Color.White, Color.Blue, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = first.Equals(second);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Not_Consider_Two_Styles_With_Different_Decorations_Equal()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
var second = new Style(Color.White, Color.Yellow, Decoration.Bold, "http://example.com");
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = first.Equals(second);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Not_Consider_Two_Styles_With_Different_Links_Equal()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var first = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://example.com");
|
||||||
|
var second = new Style(Color.White, Color.Yellow, Decoration.Bold | Decoration.Italic, "http://foo.com");
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = first.Equals(second);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TheParseMethod
|
public sealed class TheParseMethod
|
||||||
@@ -62,16 +133,36 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Should_Parse_Text_And_Decoration()
|
public void Should_Parse_Link_Without_Address()
|
||||||
{
|
{
|
||||||
// Given, When
|
// Given, When
|
||||||
var result = Style.Parse("bold underline blue on green");
|
var result = Style.Parse("link");
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
result.ShouldNotBeNull();
|
result.ShouldNotBeNull();
|
||||||
result.Decoration.ShouldBe(Decoration.Bold | Decoration.Underline);
|
result.Link.ShouldBe("https://emptylink");
|
||||||
result.Foreground.ShouldBe(Color.Blue);
|
}
|
||||||
result.Background.ShouldBe(Color.Green);
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Parse_Link()
|
||||||
|
{
|
||||||
|
// Given, When
|
||||||
|
var result = Style.Parse("link=https://example.com");
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldNotBeNull();
|
||||||
|
result.Link.ShouldBe("https://example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Throw_If_Link_Is_Set_Twice()
|
||||||
|
{
|
||||||
|
// Given, When
|
||||||
|
var result = Record.Exception(() => Style.Parse("link=https://example.com link=https://example.com"));
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldBeOfType<InvalidOperationException>();
|
||||||
|
result.Message.ShouldBe("A link has already been set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -131,6 +222,20 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
result.Message.ShouldBe("Could not find color 'lol'.");
|
result.Message.ShouldBe("Could not find color 'lol'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Parse_Colors_And_Decoration_And_Link()
|
||||||
|
{
|
||||||
|
// Given, When
|
||||||
|
var result = Style.Parse("link=https://example.com bold underline blue on green");
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ShouldNotBeNull();
|
||||||
|
result.Decoration.ShouldBe(Decoration.Bold | Decoration.Underline);
|
||||||
|
result.Foreground.ShouldBe(Color.Blue);
|
||||||
|
result.Background.ShouldBe(Color.Green);
|
||||||
|
result.Link.ShouldBe("https://example.com");
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("#FF0000 on #0000FF")]
|
[InlineData("#FF0000 on #0000FF")]
|
||||||
[InlineData("#F00 on #00F")]
|
[InlineData("#F00 on #00F")]
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
var console = new PlainConsole(width: 80);
|
var console = new PlainConsole(width: 80);
|
||||||
var table = new Table();
|
var table = new Table();
|
||||||
table.AddColumns("Foo", "Bar");
|
table.AddColumns("Foo", "Bar");
|
||||||
table.AddColumn(new TableColumn("Baz") { Padding = new Padding(3, 2) });
|
table.AddColumn(new TableColumn("Baz") { Padding = new Padding(3, 0, 2, 0) });
|
||||||
table.AddRow("Qux\nQuuux", "Corgi", "Waldo");
|
table.AddRow("Qux\nQuuux", "Corgi", "Waldo");
|
||||||
table.AddRow("Grault", "Garply", "Fred");
|
table.AddRow("Grault", "Garply", "Fred");
|
||||||
|
|
||||||
@@ -372,7 +372,7 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
var console = new PlainConsole(width: 80);
|
var console = new PlainConsole(width: 80);
|
||||||
var table = new Table();
|
var table = new Table();
|
||||||
table.AddColumns("Foo", "Bar");
|
table.AddColumns("Foo", "Bar");
|
||||||
table.AddColumn(new TableColumn("Baz") { Padding = new Padding(3, 2) });
|
table.AddColumn(new TableColumn("Baz") { Padding = new Padding(3, 0, 2, 0) });
|
||||||
|
|
||||||
// When
|
// When
|
||||||
console.Render(table);
|
console.Render(table);
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Render_Unstyled_Text_As_Expected()
|
public void Should_Render_Unstyled_Text_As_Expected()
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new PlainConsole(width: 80);
|
var console = new PlainConsole(width: 80);
|
||||||
var text = new Text("Hello World");
|
var text = new Text("Hello World");
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Render(text);
|
console.Render(text);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output
|
console.Output
|
||||||
.NormalizeLineEndings()
|
.NormalizeLineEndings()
|
||||||
.ShouldBe("Hello World");
|
.ShouldBe("Hello World");
|
||||||
}
|
}
|
||||||
@@ -55,14 +55,14 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Write_Line_Breaks(string input)
|
public void Should_Write_Line_Breaks(string input)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new PlainConsole(width: 5);
|
var console = new PlainConsole(width: 5);
|
||||||
var text = new Text(input);
|
var text = new Text(input);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Render(text);
|
console.Render(text);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.RawOutput.ShouldBe("Hello\n\nWorld\n\n");
|
console.RawOutput.ShouldBe("Hello\n\nWorld\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -87,14 +87,14 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
int width, string input, string expected)
|
int width, string input, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new PlainConsole(width);
|
var console = new PlainConsole(width);
|
||||||
var text = new Text(input);
|
var text = new Text(input);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Render(text);
|
console.Render(text);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output
|
console.Output
|
||||||
.NormalizeLineEndings()
|
.NormalizeLineEndings()
|
||||||
.ShouldBe(expected);
|
.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
@@ -106,15 +106,15 @@ namespace Spectre.Console.Tests.Unit
|
|||||||
public void Should_Overflow_Text_Correctly(Overflow overflow, string expected)
|
public void Should_Overflow_Text_Correctly(Overflow overflow, string expected)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
var fixture = new PlainConsole(14);
|
var console = new PlainConsole(14);
|
||||||
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
|
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
|
||||||
.SetOverflow(overflow);
|
.SetOverflow(overflow);
|
||||||
|
|
||||||
// When
|
// When
|
||||||
fixture.Render(text);
|
console.Render(text);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fixture.Output
|
console.Output
|
||||||
.NormalizeLineEndings()
|
.NormalizeLineEndings()
|
||||||
.ShouldBe(expected);
|
.ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Columns", "..\examples\Colu
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Info", "..\examples\Info\Info.csproj", "{225CE0D4-06AB-411A-8D29-707504FE53B3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Info", "..\examples\Info\Info.csproj", "{225CE0D4-06AB-411A-8D29-707504FE53B3}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borders", "..\examples\Borders\Borders.csproj", "{094245E6-4C94-485D-B5AC-3153E878B112}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Borders", "..\examples\Borders\Borders.csproj", "{094245E6-4C94-485D-B5AC-3153E878B112}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Links", "..\examples\Links\Links.csproj", "{6AF8C93B-AA41-4F44-8B1B-B8D166576174}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emojis", "..\examples\Emojis\Emojis.csproj", "{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -149,6 +153,30 @@ Global
|
|||||||
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x64.Build.0 = Release|Any CPU
|
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.ActiveCfg = Release|Any CPU
|
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.Build.0 = Release|Any CPU
|
{094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -161,6 +189,8 @@ Global
|
|||||||
{33357599-C79D-4299-888F-634E2C3EACEF} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
{33357599-C79D-4299-888F-634E2C3EACEF} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||||
{225CE0D4-06AB-411A-8D29-707504FE53B3} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
{225CE0D4-06AB-411A-8D29-707504FE53B3} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||||
{094245E6-4C94-485D-B5AC-3153E878B112} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
{094245E6-4C94-485D-B5AC-3153E878B112} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||||
|
{6AF8C93B-AA41-4F44-8B1B-B8D166576174} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||||
|
{1EABB956-957F-4C1A-8AC0-FD19C8F3C2F2} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
|
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
|
||||||
|
|||||||
85
src/Spectre.Console/AnsiConsole.State.cs
Normal file
85
src/Spectre.Console/AnsiConsole.State.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Spectre.Console.Internal;
|
||||||
|
|
||||||
|
namespace Spectre.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A console capable of writing ANSI escape sequences.
|
||||||
|
/// </summary>
|
||||||
|
public static partial class AnsiConsole
|
||||||
|
{
|
||||||
|
private static ConsoleColor _defaultForeground;
|
||||||
|
private static ConsoleColor _defaultBackground;
|
||||||
|
|
||||||
|
internal static Style CurrentStyle { get; private set; } = Style.Plain;
|
||||||
|
internal static bool Created { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the foreground color.
|
||||||
|
/// </summary>
|
||||||
|
public static Color Foreground
|
||||||
|
{
|
||||||
|
get => CurrentStyle.Foreground;
|
||||||
|
set => CurrentStyle = CurrentStyle.WithForeground(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the background color.
|
||||||
|
/// </summary>
|
||||||
|
public static Color Background
|
||||||
|
{
|
||||||
|
get => CurrentStyle.Background;
|
||||||
|
set => CurrentStyle = CurrentStyle.WithBackground(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the text decoration.
|
||||||
|
/// </summary>
|
||||||
|
public static Decoration Decoration
|
||||||
|
{
|
||||||
|
get => CurrentStyle.Decoration;
|
||||||
|
set => CurrentStyle = CurrentStyle.WithDecoration(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Initialize(TextWriter? @out)
|
||||||
|
{
|
||||||
|
if (@out?.IsStandardOut() ?? false)
|
||||||
|
{
|
||||||
|
Foreground = _defaultForeground = System.Console.ForegroundColor;
|
||||||
|
Background = _defaultBackground = System.Console.BackgroundColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Foreground = _defaultForeground = Color.Silver;
|
||||||
|
Background = _defaultBackground = Color.Black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets colors and text decorations.
|
||||||
|
/// </summary>
|
||||||
|
public static void Reset()
|
||||||
|
{
|
||||||
|
ResetColors();
|
||||||
|
ResetDecoration();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the current applied text decorations.
|
||||||
|
/// </summary>
|
||||||
|
public static void ResetDecoration()
|
||||||
|
{
|
||||||
|
Decoration = Decoration.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the current applied foreground and background colors.
|
||||||
|
/// </summary>
|
||||||
|
public static void ResetColors()
|
||||||
|
{
|
||||||
|
Foreground = _defaultForeground;
|
||||||
|
Background = _defaultBackground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(string value)
|
public static void Write(string value)
|
||||||
{
|
{
|
||||||
Console.Write(value);
|
Console.Write(value, CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -24,7 +24,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(int value)
|
public static void Write(int value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,7 +35,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, int value)
|
public static void Write(IFormatProvider provider, int value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -45,7 +45,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(uint value)
|
public static void Write(uint value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -56,7 +56,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, uint value)
|
public static void Write(IFormatProvider provider, uint value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -66,7 +66,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(long value)
|
public static void Write(long value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -77,7 +77,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, long value)
|
public static void Write(IFormatProvider provider, long value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -87,7 +87,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(ulong value)
|
public static void Write(ulong value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -98,7 +98,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, ulong value)
|
public static void Write(IFormatProvider provider, ulong value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -108,7 +108,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(float value)
|
public static void Write(float value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -119,7 +119,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, float value)
|
public static void Write(IFormatProvider provider, float value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -129,7 +129,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(double value)
|
public static void Write(double value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -140,7 +140,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, double value)
|
public static void Write(IFormatProvider provider, double value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -149,7 +149,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(decimal value)
|
public static void Write(decimal value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -159,7 +159,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, decimal value)
|
public static void Write(IFormatProvider provider, decimal value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -168,7 +168,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(bool value)
|
public static void Write(bool value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -178,7 +178,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, bool value)
|
public static void Write(IFormatProvider provider, bool value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -187,7 +187,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(char value)
|
public static void Write(char value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -197,7 +197,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, char value)
|
public static void Write(IFormatProvider provider, char value)
|
||||||
{
|
{
|
||||||
Console.Write(value.ToString(provider));
|
Console.Write(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -206,7 +206,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(char[] value)
|
public static void Write(char[] value)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, value);
|
Write(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -216,7 +216,15 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void Write(IFormatProvider provider, char[] value)
|
public static void Write(IFormatProvider provider, char[] value)
|
||||||
{
|
{
|
||||||
Console.Write(provider, value);
|
if (value is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var index = 0; index < value.Length; index++)
|
||||||
|
{
|
||||||
|
Console.Write(value[index].ToString(provider), CurrentStyle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -227,7 +235,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="args">An array of objects to write.</param>
|
/// <param name="args">An array of objects to write.</param>
|
||||||
public static void Write(string format, params object[] args)
|
public static void Write(string format, params object[] args)
|
||||||
{
|
{
|
||||||
Console.Write(CultureInfo.CurrentCulture, format, args);
|
Write(CultureInfo.CurrentCulture, format, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -239,7 +247,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="args">An array of objects to write.</param>
|
/// <param name="args">An array of objects to write.</param>
|
||||||
public static void Write(IFormatProvider provider, string format, params object[] args)
|
public static void Write(IFormatProvider provider, string format, params object[] args)
|
||||||
{
|
{
|
||||||
Console.Write(string.Format(provider, format, args));
|
Console.Write(string.Format(provider, format, args), CurrentStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(string value)
|
public static void WriteLine(string value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value);
|
Console.WriteLine(value, CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -32,7 +32,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(int value)
|
public static void WriteLine(int value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -43,7 +43,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, int value)
|
public static void WriteLine(IFormatProvider provider, int value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -53,7 +53,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(uint value)
|
public static void WriteLine(uint value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -64,7 +64,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, uint value)
|
public static void WriteLine(IFormatProvider provider, uint value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -74,7 +74,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(long value)
|
public static void WriteLine(long value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -85,7 +85,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, long value)
|
public static void WriteLine(IFormatProvider provider, long value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -95,7 +95,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(ulong value)
|
public static void WriteLine(ulong value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -106,7 +106,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, ulong value)
|
public static void WriteLine(IFormatProvider provider, ulong value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -116,7 +116,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(float value)
|
public static void WriteLine(float value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -127,7 +127,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, float value)
|
public static void WriteLine(IFormatProvider provider, float value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -137,7 +137,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(double value)
|
public static void WriteLine(double value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -148,7 +148,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, double value)
|
public static void WriteLine(IFormatProvider provider, double value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -158,7 +158,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(decimal value)
|
public static void WriteLine(decimal value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -169,7 +169,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, decimal value)
|
public static void WriteLine(IFormatProvider provider, decimal value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -179,7 +179,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(bool value)
|
public static void WriteLine(bool value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -190,7 +190,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, bool value)
|
public static void WriteLine(IFormatProvider provider, bool value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -200,7 +200,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(char value)
|
public static void WriteLine(char value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -211,7 +211,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, char value)
|
public static void WriteLine(IFormatProvider provider, char value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(value.ToString(provider));
|
Console.WriteLine(value.ToString(provider), CurrentStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -221,7 +221,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(char[] value)
|
public static void WriteLine(char[] value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, value);
|
WriteLine(CultureInfo.CurrentCulture, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -232,7 +232,17 @@ namespace Spectre.Console
|
|||||||
/// <param name="value">The value to write.</param>
|
/// <param name="value">The value to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, char[] value)
|
public static void WriteLine(IFormatProvider provider, char[] value)
|
||||||
{
|
{
|
||||||
Console.WriteLine(provider, value);
|
if (value is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var index = 0; index < value.Length; index++)
|
||||||
|
{
|
||||||
|
Console.Write(value[index].ToString(provider), CurrentStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -244,7 +254,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="args">An array of objects to write.</param>
|
/// <param name="args">An array of objects to write.</param>
|
||||||
public static void WriteLine(string format, params object[] args)
|
public static void WriteLine(string format, params object[] args)
|
||||||
{
|
{
|
||||||
Console.WriteLine(CultureInfo.CurrentCulture, format, args);
|
WriteLine(CultureInfo.CurrentCulture, format, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -257,7 +267,7 @@ namespace Spectre.Console
|
|||||||
/// <param name="args">An array of objects to write.</param>
|
/// <param name="args">An array of objects to write.</param>
|
||||||
public static void WriteLine(IFormatProvider provider, string format, params object[] args)
|
public static void WriteLine(IFormatProvider provider, string format, params object[] args)
|
||||||
{
|
{
|
||||||
Console.WriteLine(string.Format(provider, format, args));
|
Console.WriteLine(string.Format(provider, format, args), CurrentStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ namespace Spectre.Console
|
|||||||
ColorSystem = ColorSystemSupport.Detect,
|
ColorSystem = ColorSystemSupport.Detect,
|
||||||
Out = System.Console.Out,
|
Out = System.Console.Out,
|
||||||
});
|
});
|
||||||
|
Initialize(System.Console.Out);
|
||||||
Created = true;
|
Created = true;
|
||||||
return console;
|
return console;
|
||||||
});
|
});
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current renderer.
|
/// Gets the underlying <see cref="IAnsiConsole"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IAnsiConsole Console => _console.Value;
|
public static IAnsiConsole Console => _console.Value;
|
||||||
|
|
||||||
@@ -30,8 +31,6 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static Capabilities Capabilities => Console.Capabilities;
|
public static Capabilities Capabilities => Console.Capabilities;
|
||||||
|
|
||||||
internal static bool Created { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the buffer width of the console.
|
/// Gets the buffer width of the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -48,33 +47,6 @@ namespace Spectre.Console
|
|||||||
get => Console.Height;
|
get => Console.Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the foreground color.
|
|
||||||
/// </summary>
|
|
||||||
public static Color Foreground
|
|
||||||
{
|
|
||||||
get => Console.Foreground;
|
|
||||||
set => Console.SetColor(value, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the background color.
|
|
||||||
/// </summary>
|
|
||||||
public static Color Background
|
|
||||||
{
|
|
||||||
get => Console.Background;
|
|
||||||
set => Console.SetColor(value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the text decoration.
|
|
||||||
/// </summary>
|
|
||||||
public static Decoration Decoration
|
|
||||||
{
|
|
||||||
get => Console.Decoration;
|
|
||||||
set => Console.Decoration = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="IAnsiConsole"/> instance
|
/// Creates a new <see cref="IAnsiConsole"/> instance
|
||||||
/// from the provided settings.
|
/// from the provided settings.
|
||||||
@@ -83,31 +55,7 @@ namespace Spectre.Console
|
|||||||
/// <returns>An <see cref="IAnsiConsole"/> instance.</returns>
|
/// <returns>An <see cref="IAnsiConsole"/> instance.</returns>
|
||||||
public static IAnsiConsole Create(AnsiConsoleSettings settings)
|
public static IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||||
{
|
{
|
||||||
return ConsoleBuilder.Build(settings);
|
return AnsiConsoleBuilder.Build(settings);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resets colors and text decorations.
|
|
||||||
/// </summary>
|
|
||||||
public static void Reset()
|
|
||||||
{
|
|
||||||
Console.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resets the current applied text decorations.
|
|
||||||
/// </summary>
|
|
||||||
public static void ResetDecoration()
|
|
||||||
{
|
|
||||||
Console.ResetDecoration();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resets the current applied foreground and background colors.
|
|
||||||
/// </summary>
|
|
||||||
public static void ResetColors()
|
|
||||||
{
|
|
||||||
Console.ResetColors();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ColorSystemSupport ColorSystem { get; set; }
|
public ColorSystemSupport ColorSystem { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the link identity generator.
|
||||||
|
/// </summary>
|
||||||
|
public ILinkIdentityGenerator? LinkIdentityGenerator { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the out buffer.
|
/// Gets or sets the out buffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -11,6 +11,17 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SupportsAnsi { get; }
|
public bool SupportsAnsi { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether or not
|
||||||
|
/// the console support links.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// There is probably a lot of room for improvement here
|
||||||
|
/// once we have more information about the terminal
|
||||||
|
/// we're running inside.
|
||||||
|
/// </remarks>
|
||||||
|
public bool SupportLinks => SupportsAnsi && !LegacyConsole;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the color system.
|
/// Gets the color system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
// Generated 2020-08-03 15:17
|
// Generated 2020-09-18 10:42
|
||||||
//
|
//
|
||||||
// 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.
|
||||||
|
|||||||
9300
src/Spectre.Console/Emoji.Generated.cs
Normal file
9300
src/Spectre.Console/Emoji.Generated.cs
Normal file
File diff suppressed because it is too large
Load Diff
23
src/Spectre.Console/Emoji.cs
Normal file
23
src/Spectre.Console/Emoji.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Spectre.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Utility for working with emojis.
|
||||||
|
/// </summary>
|
||||||
|
public static partial class Emoji
|
||||||
|
{
|
||||||
|
private static readonly Regex _emojiCode = new Regex(@"(:(\S*?):)", RegexOptions.Compiled);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replaces emoji markup with corresponding unicode characters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">A string with emojis codes, e.g. "Hello :smiley:!".</param>
|
||||||
|
/// <returns>A string with emoji codes replaced with actual emoji.</returns>
|
||||||
|
public static string Replace(string value)
|
||||||
|
{
|
||||||
|
static string ReplaceEmoji(Match match) => _emojis[match.Groups[2].Value];
|
||||||
|
return _emojiCode.Replace(value, ReplaceEmoji);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Spectre.Console.Internal;
|
|
||||||
using Spectre.Console.Rendering;
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
namespace Spectre.Console
|
namespace Spectre.Console
|
||||||
@@ -28,9 +27,6 @@ namespace Spectre.Console
|
|||||||
}
|
}
|
||||||
|
|
||||||
var options = new RenderContext(console.Encoding, console.Capabilities.LegacyConsole);
|
var options = new RenderContext(console.Encoding, console.Capabilities.LegacyConsole);
|
||||||
|
|
||||||
using (console.PushStyle(Style.Plain))
|
|
||||||
{
|
|
||||||
var segments = renderable.Render(options, console.Width).Where(x => !(x.Text.Length == 0 && !x.IsLineBreak)).ToArray();
|
var segments = renderable.Render(options, console.Width).Where(x => !(x.Text.Length == 0 && !x.IsLineBreak)).ToArray();
|
||||||
segments = Segment.Merge(segments).ToArray();
|
segments = Segment.Merge(segments).ToArray();
|
||||||
|
|
||||||
@@ -42,16 +38,7 @@ namespace Spectre.Console
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!segment.Style.Equals(current))
|
console.Write(segment.Text, segment.Style);
|
||||||
{
|
|
||||||
console.Foreground = segment.Style.Foreground;
|
|
||||||
console.Background = segment.Style.Background;
|
|
||||||
console.Decoration = segment.Style.Decoration;
|
|
||||||
current = segment.Style;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(segment.Text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,339 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace Spectre.Console
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Contains extension methods for <see cref="IAnsiConsole"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static partial class AnsiConsoleExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified string value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, string value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
console.Write(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit
|
|
||||||
/// signed integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, int value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit
|
|
||||||
/// signed integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, int value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit
|
|
||||||
/// unsigned integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, uint value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit
|
|
||||||
/// unsigned integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, uint value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit
|
|
||||||
/// signed integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, long value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit
|
|
||||||
/// signed integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, long value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit
|
|
||||||
/// unsigned integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, ulong value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit
|
|
||||||
/// unsigned integer value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, ulong value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified single-precision
|
|
||||||
/// floating-point value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, float value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified single-precision
|
|
||||||
/// floating-point value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, float value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified double-precision
|
|
||||||
/// floating-point value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, double value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified double-precision
|
|
||||||
/// floating-point value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, double value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified decimal value, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, decimal value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified decimal value, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, decimal value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
Write(console, value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified boolean value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, bool value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified boolean value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, bool value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
Write(console, value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified Unicode character to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, char value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified Unicode character to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, char value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
Write(console, value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified array of Unicode characters to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, char[] value)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified array of Unicode characters to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, char[] value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var index = 0; index < value.Length; index++)
|
|
||||||
{
|
|
||||||
console.Write(value[index].ToString(provider));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified array of objects,
|
|
||||||
/// to the console using the specified format information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="format">A composite format string.</param>
|
|
||||||
/// <param name="args">An array of objects to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, string format, params object[] args)
|
|
||||||
{
|
|
||||||
Write(console, CultureInfo.CurrentCulture, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified array of objects,
|
|
||||||
/// to the console using the specified format information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="format">A composite format string.</param>
|
|
||||||
/// <param name="args">An array of objects to write.</param>
|
|
||||||
public static void Write(this IAnsiConsole console, IFormatProvider provider, string format, params object[] args)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
Write(console, string.Format(provider, format, args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,368 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace Spectre.Console
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Contains extension methods for <see cref="IAnsiConsole"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static partial class AnsiConsoleExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Writes an empty line to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Write(Environment.NewLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified string value, followed by the
|
|
||||||
/// current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, string value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
console.Write(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit signed integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, int value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit signed integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, int value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit unsigned integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, uint value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 32-bit unsigned integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, uint value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit signed integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, long value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit signed integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, long value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit unsigned integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, ulong value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified 64-bit unsigned integer value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, ulong value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified single-precision floating-point
|
|
||||||
/// value, followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, float value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified single-precision floating-point
|
|
||||||
/// value, followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, float value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified double-precision floating-point
|
|
||||||
/// value, followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, double value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified double-precision floating-point
|
|
||||||
/// value, followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, double value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine(value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified decimal value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, decimal value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified decimal value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, decimal value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteLine(console, value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified boolean value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, bool value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified boolean value,
|
|
||||||
/// followed by the current line terminator, to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, bool value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteLine(console, value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified Unicode character, followed by the current
|
|
||||||
/// line terminator, value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, char value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified Unicode character, followed by the current
|
|
||||||
/// line terminator, value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, char value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteLine(console, value.ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified array of Unicode characters, followed by the current
|
|
||||||
/// line terminator, value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, char[] value)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the specified array of Unicode characters, followed by the current
|
|
||||||
/// line terminator, value to the console.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="value">The value to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, char[] value)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var index = 0; index < value.Length; index++)
|
|
||||||
{
|
|
||||||
console.Write(value[index].ToString(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified array of objects,
|
|
||||||
/// followed by the current line terminator, to the console
|
|
||||||
/// using the specified format information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="format">A composite format string.</param>
|
|
||||||
/// <param name="args">An array of objects to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, string format, params object[] args)
|
|
||||||
{
|
|
||||||
WriteLine(console, CultureInfo.CurrentCulture, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Writes the text representation of the specified array of objects,
|
|
||||||
/// followed by the current line terminator, to the console
|
|
||||||
/// using the specified format information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to write to.</param>
|
|
||||||
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
|
|
||||||
/// <param name="format">A composite format string.</param>
|
|
||||||
/// <param name="args">An array of objects to write.</param>
|
|
||||||
public static void WriteLine(this IAnsiConsole console, IFormatProvider provider, string format, params object[] args)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteLine(console, string.Format(provider, format, args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,47 +8,34 @@ namespace Spectre.Console
|
|||||||
public static partial class AnsiConsoleExtensions
|
public static partial class AnsiConsoleExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets colors and text decorations.
|
/// Writes an empty line to the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="console">The console to reset.</param>
|
/// <param name="console">The console to write to.</param>
|
||||||
public static void Reset(this IAnsiConsole console)
|
public static void WriteLine(this IAnsiConsole console)
|
||||||
{
|
{
|
||||||
if (console is null)
|
if (console is null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(console));
|
throw new ArgumentNullException(nameof(console));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.ResetColors();
|
console.Write(Environment.NewLine, Style.Plain);
|
||||||
console.ResetDecoration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets the current applied text decorations.
|
/// Writes the specified string value, followed by the current line terminator, to the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="console">The console to reset the text decorations for.</param>
|
/// <param name="console">The console to write to.</param>
|
||||||
public static void ResetDecoration(this IAnsiConsole console)
|
/// <param name="text">The text to write.</param>
|
||||||
|
/// <param name="style">The text style.</param>
|
||||||
|
public static void WriteLine(this IAnsiConsole console, string text, Style style)
|
||||||
{
|
{
|
||||||
if (console is null)
|
if (console is null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(console));
|
throw new ArgumentNullException(nameof(console));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.Decoration = Decoration.None;
|
console.Write(text, style);
|
||||||
}
|
console.WriteLine();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resets the current applied foreground and background colors.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="console">The console to reset colors for.</param>
|
|
||||||
public static void ResetColors(this IAnsiConsole console)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.Foreground = Color.Default;
|
|
||||||
console.Background = Color.Default;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
||||||
/// <param name="obj">The paddable object instance.</param>
|
/// <param name="obj">The paddable object instance.</param>
|
||||||
/// <param name="padding">The left padding to apply.</param>
|
/// <param name="left">The left padding.</param>
|
||||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||||
public static T PadLeft<T>(this T obj, int padding)
|
public static T PadLeft<T>(this T obj, int left)
|
||||||
where T : class, IPaddable
|
where T : class, IPaddable
|
||||||
{
|
{
|
||||||
if (obj is null)
|
if (obj is null)
|
||||||
@@ -22,7 +22,25 @@ namespace Spectre.Console
|
|||||||
throw new ArgumentNullException(nameof(obj));
|
throw new ArgumentNullException(nameof(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetPadding(obj, new Padding(padding, obj.Padding.Right));
|
return SetPadding(obj, new Padding(left, obj.Padding.Top, obj.Padding.Right, obj.Padding.Bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the top padding.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
||||||
|
/// <param name="obj">The paddable object instance.</param>
|
||||||
|
/// <param name="top">The top padding.</param>
|
||||||
|
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||||
|
public static T PadTop<T>(this T obj, int top)
|
||||||
|
where T : class, IPaddable
|
||||||
|
{
|
||||||
|
if (obj is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetPadding(obj, new Padding(obj.Padding.Left, top, obj.Padding.Right, obj.Padding.Bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -30,9 +48,9 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
||||||
/// <param name="obj">The paddable object instance.</param>
|
/// <param name="obj">The paddable object instance.</param>
|
||||||
/// <param name="padding">The right padding to apply.</param>
|
/// <param name="right">The right padding.</param>
|
||||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||||
public static T PadRight<T>(this T obj, int padding)
|
public static T PadRight<T>(this T obj, int right)
|
||||||
where T : class, IPaddable
|
where T : class, IPaddable
|
||||||
{
|
{
|
||||||
if (obj is null)
|
if (obj is null)
|
||||||
@@ -40,7 +58,25 @@ namespace Spectre.Console
|
|||||||
throw new ArgumentNullException(nameof(obj));
|
throw new ArgumentNullException(nameof(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetPadding(obj, new Padding(obj.Padding.Left, padding));
|
return SetPadding(obj, new Padding(obj.Padding.Left, obj.Padding.Top, right, obj.Padding.Bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the bottom padding.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
||||||
|
/// <param name="obj">The paddable object instance.</param>
|
||||||
|
/// <param name="bottom">The bottom padding.</param>
|
||||||
|
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||||
|
public static T PadBottom<T>(this T obj, int bottom)
|
||||||
|
where T : class, IPaddable
|
||||||
|
{
|
||||||
|
if (obj is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetPadding(obj, new Padding(obj.Padding.Left, obj.Padding.Top, obj.Padding.Right, bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -49,12 +85,14 @@ namespace Spectre.Console
|
|||||||
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
/// <typeparam name="T">An object implementing <see cref="IPaddable"/>.</typeparam>
|
||||||
/// <param name="obj">The paddable object instance.</param>
|
/// <param name="obj">The paddable object instance.</param>
|
||||||
/// <param name="left">The left padding to apply.</param>
|
/// <param name="left">The left padding to apply.</param>
|
||||||
|
/// <param name="top">The top padding to apply.</param>
|
||||||
/// <param name="right">The right padding to apply.</param>
|
/// <param name="right">The right padding to apply.</param>
|
||||||
|
/// <param name="bottom">The bottom padding to apply.</param>
|
||||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||||
public static T SetPadding<T>(this T obj, int left, int right)
|
public static T SetPadding<T>(this T obj, int left, int top, int right, int bottom)
|
||||||
where T : class, IPaddable
|
where T : class, IPaddable
|
||||||
{
|
{
|
||||||
return SetPadding(obj, new Padding(left, right));
|
return SetPadding(obj, new Padding(left, top, right, bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -66,5 +66,26 @@ namespace Spectre.Console
|
|||||||
background: style.Background,
|
background: style.Background,
|
||||||
decoration: decoration);
|
decoration: decoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new style from the specified one with
|
||||||
|
/// the specified link.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="style">The style.</param>
|
||||||
|
/// <param name="link">The link.</param>
|
||||||
|
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||||
|
public static Style WithLink(this Style style, string link)
|
||||||
|
{
|
||||||
|
if (style is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(style));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Style(
|
||||||
|
foreground: style.Foreground,
|
||||||
|
background: style.Background,
|
||||||
|
decoration: style.Decoration,
|
||||||
|
link: link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Capabilities Capabilities { get; }
|
Capabilities Capabilities { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the console output encoding.
|
||||||
|
/// </summary>
|
||||||
|
Encoding Encoding { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the buffer width of the console.
|
/// Gets the buffer width of the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -22,30 +27,11 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
int Height { get; }
|
int Height { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the console output encoding.
|
|
||||||
/// </summary>
|
|
||||||
Encoding Encoding { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the current text decoration.
|
|
||||||
/// </summary>
|
|
||||||
Decoration Decoration { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the current foreground.
|
|
||||||
/// </summary>
|
|
||||||
Color Foreground { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the current background.
|
|
||||||
/// </summary>
|
|
||||||
Color Background { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a string followed by a line terminator to the console.
|
/// Writes a string followed by a line terminator to the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">The string to write.</param>
|
/// <param name="text">The string to write.</param>
|
||||||
void Write(string text);
|
/// <param name="style">The style to use.</param>
|
||||||
|
void Write(string text, Style style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/Spectre.Console/ILinkIdentityGenerator.cs
Normal file
16
src/Spectre.Console/ILinkIdentityGenerator.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace Spectre.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a link identity generator.
|
||||||
|
/// </summary>
|
||||||
|
public interface ILinkIdentityGenerator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Generates an ID for the given link.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="link">The link.</param>
|
||||||
|
/// <param name="text">The link text.</param>
|
||||||
|
/// <returns>A unique ID for the link.</returns>
|
||||||
|
public int GenerateId(string link, string text);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,44 +1,74 @@
|
|||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Spectre.Console.Internal
|
namespace Spectre.Console.Internal
|
||||||
{
|
{
|
||||||
internal static class AnsiBuilder
|
internal sealed class AnsiBuilder
|
||||||
{
|
{
|
||||||
public static string GetAnsi(
|
private readonly Capabilities _capabilities;
|
||||||
ColorSystem system,
|
private readonly ILinkIdentityGenerator _linkHasher;
|
||||||
string text,
|
|
||||||
Decoration decoration,
|
public AnsiBuilder(Capabilities capabilities, ILinkIdentityGenerator? linkHasher)
|
||||||
Color foreground,
|
|
||||||
Color background)
|
|
||||||
{
|
{
|
||||||
var codes = AnsiDecorationBuilder.GetAnsiCodes(decoration);
|
_capabilities = capabilities ?? throw new ArgumentNullException(nameof(capabilities));
|
||||||
|
_linkHasher = linkHasher ?? new LinkIdentityGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetAnsi(string text, Style style)
|
||||||
|
{
|
||||||
|
if (style is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(style));
|
||||||
|
}
|
||||||
|
|
||||||
|
var codes = AnsiDecorationBuilder.GetAnsiCodes(style.Decoration);
|
||||||
|
|
||||||
// Got foreground?
|
// Got foreground?
|
||||||
if (foreground != Color.Default)
|
if (style.Foreground != Color.Default)
|
||||||
{
|
{
|
||||||
codes = codes.Concat(AnsiColorBuilder.GetAnsiCodes(system, foreground, foreground: true));
|
codes = codes.Concat(
|
||||||
|
AnsiColorBuilder.GetAnsiCodes(
|
||||||
|
_capabilities.ColorSystem,
|
||||||
|
style.Foreground,
|
||||||
|
true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Got background?
|
// Got background?
|
||||||
if (background != Color.Default)
|
if (style.Background != Color.Default)
|
||||||
{
|
{
|
||||||
codes = codes.Concat(AnsiColorBuilder.GetAnsiCodes(system, background, foreground: false));
|
codes = codes.Concat(
|
||||||
|
AnsiColorBuilder.GetAnsiCodes(
|
||||||
|
_capabilities.ColorSystem,
|
||||||
|
style.Background,
|
||||||
|
false));
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = codes.ToArray();
|
var result = codes.ToArray();
|
||||||
if (result.Length == 0)
|
if (result.Length == 0 && style.Link == null)
|
||||||
{
|
{
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lol = string.Concat(
|
var ansiCodes = string.Join(";", result);
|
||||||
"\u001b[",
|
var ansi = result.Length > 0
|
||||||
string.Join(";", result),
|
? $"\u001b[{ansiCodes}m{text}\u001b[0m"
|
||||||
"m",
|
: text;
|
||||||
text,
|
|
||||||
"\u001b[0m");
|
|
||||||
|
|
||||||
return lol;
|
if (style.Link != null && !_capabilities.LegacyConsole)
|
||||||
|
{
|
||||||
|
var link = style.Link;
|
||||||
|
|
||||||
|
// Empty links means we should take the URL from the text.
|
||||||
|
if (link.Equals(Constants.EmptyLink, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
link = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
var linkId = _linkHasher.GenerateId(link, text);
|
||||||
|
ansi = $"\u001b]8;id={linkId};{link}\u001b\\{ansi}\u001b]8;;\u001b\\";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ansi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace Spectre.Console.Internal
|
namespace Spectre.Console.Internal
|
||||||
{
|
{
|
||||||
internal static class ConsoleBuilder
|
internal static class AnsiConsoleBuilder
|
||||||
{
|
{
|
||||||
public static IAnsiConsole Build(AnsiConsoleSettings settings)
|
public static IAnsiConsole Build(AnsiConsoleSettings settings)
|
||||||
{
|
{
|
||||||
@@ -54,15 +54,18 @@ namespace Spectre.Console.Internal
|
|||||||
? ColorSystemDetector.Detect(supportsAnsi)
|
? ColorSystemDetector.Detect(supportsAnsi)
|
||||||
: (ColorSystem)settings.ColorSystem;
|
: (ColorSystem)settings.ColorSystem;
|
||||||
|
|
||||||
|
// Get the capabilities
|
||||||
|
var capabilities = new Capabilities(supportsAnsi, colorSystem, legacyConsole);
|
||||||
|
|
||||||
|
// Create the renderer
|
||||||
if (supportsAnsi)
|
if (supportsAnsi)
|
||||||
{
|
{
|
||||||
return new AnsiConsoleRenderer(buffer, colorSystem, legacyConsole)
|
return new AnsiConsoleRenderer(buffer, capabilities, settings.LinkIdentityGenerator);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Decoration = Decoration.None,
|
return new FallbackConsoleRenderer(buffer, capabilities);
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return new FallbackConsoleRenderer(buffer, colorSystem, legacyConsole);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,13 +7,10 @@ namespace Spectre.Console.Internal
|
|||||||
internal sealed class AnsiConsoleRenderer : IAnsiConsole
|
internal sealed class AnsiConsoleRenderer : IAnsiConsole
|
||||||
{
|
{
|
||||||
private readonly TextWriter _out;
|
private readonly TextWriter _out;
|
||||||
private readonly ColorSystem _system;
|
private readonly AnsiBuilder _ansiBuilder;
|
||||||
|
|
||||||
public Capabilities Capabilities { get; }
|
public Capabilities Capabilities { get; }
|
||||||
public Encoding Encoding { get; }
|
public Encoding Encoding { get; }
|
||||||
public Decoration Decoration { get; set; }
|
|
||||||
public Color Foreground { get; set; }
|
|
||||||
public Color Background { get; set; }
|
|
||||||
|
|
||||||
public int Width
|
public int Width
|
||||||
{
|
{
|
||||||
@@ -41,31 +38,31 @@ namespace Spectre.Console.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnsiConsoleRenderer(TextWriter @out, ColorSystem system, bool legacyConsole)
|
public AnsiConsoleRenderer(TextWriter @out, Capabilities capabilities, ILinkIdentityGenerator? linkHasher)
|
||||||
{
|
{
|
||||||
_out = @out ?? throw new ArgumentNullException(nameof(@out));
|
_out = @out ?? throw new ArgumentNullException(nameof(@out));
|
||||||
_system = system;
|
|
||||||
|
|
||||||
Capabilities = new Capabilities(true, system, legacyConsole);
|
Capabilities = capabilities ?? throw new ArgumentNullException(nameof(capabilities));
|
||||||
Encoding = @out.IsStandardOut() ? System.Console.OutputEncoding : Encoding.UTF8;
|
Encoding = _out.IsStandardOut() ? System.Console.OutputEncoding : Encoding.UTF8;
|
||||||
Foreground = Color.Default;
|
|
||||||
Background = Color.Default;
|
_ansiBuilder = new AnsiBuilder(Capabilities, linkHasher);
|
||||||
Decoration = Decoration.None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(string text)
|
public void Write(string text, Style style)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(text))
|
if (string.IsNullOrEmpty(text))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style ??= Style.Plain;
|
||||||
|
|
||||||
var parts = text.NormalizeLineEndings().Split(new[] { '\n' });
|
var parts = text.NormalizeLineEndings().Split(new[] { '\n' });
|
||||||
foreach (var (_, _, last, part) in parts.Enumerate())
|
foreach (var (_, _, last, part) in parts.Enumerate())
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(part))
|
if (!string.IsNullOrEmpty(part))
|
||||||
{
|
{
|
||||||
_out.Write(AnsiBuilder.GetAnsi(_system, part, Decoration, Foreground, Background));
|
_out.Write(_ansiBuilder.GetAnsi(part, style));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!last)
|
if (!last)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
// Generated 2020-08-03 15:17
|
// Generated 2020-09-18 10:42
|
||||||
//
|
//
|
||||||
// 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 2020-08-03 15:17
|
// Generated 2020-09-18 10:42
|
||||||
//
|
//
|
||||||
// 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.
|
||||||
|
|||||||
@@ -4,5 +4,7 @@ namespace Spectre.Console.Internal
|
|||||||
{
|
{
|
||||||
public const int DefaultBufferWidth = 80;
|
public const int DefaultBufferWidth = 80;
|
||||||
public const int DefaultBufferHeight = 9001;
|
public const int DefaultBufferHeight = 9001;
|
||||||
|
|
||||||
|
public const string EmptyLink = "https://emptylink";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Spectre.Console.Internal
|
|
||||||
{
|
|
||||||
internal static class AnsiConsoleExtensions
|
|
||||||
{
|
|
||||||
public static IDisposable PushStyle(this IAnsiConsole console, Style style)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (style is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(style));
|
|
||||||
}
|
|
||||||
|
|
||||||
var current = new Style(console.Foreground, console.Background, console.Decoration);
|
|
||||||
console.SetColor(style.Foreground, true);
|
|
||||||
console.SetColor(style.Background, false);
|
|
||||||
console.Decoration = style.Decoration;
|
|
||||||
return new StyleScope(console, current);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IDisposable PushColor(this IAnsiConsole console, Color color, bool foreground)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
var current = foreground ? console.Foreground : console.Background;
|
|
||||||
console.SetColor(color, foreground);
|
|
||||||
return new ColorScope(console, current, foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IDisposable PushDecoration(this IAnsiConsole console, Decoration decoration)
|
|
||||||
{
|
|
||||||
if (console is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(console));
|
|
||||||
}
|
|
||||||
|
|
||||||
var current = console.Decoration;
|
|
||||||
console.Decoration = decoration;
|
|
||||||
return new DecorationScope(console, current);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class StyleScope : IDisposable
|
|
||||||
{
|
|
||||||
private readonly IAnsiConsole _console;
|
|
||||||
private readonly Style _style;
|
|
||||||
|
|
||||||
public StyleScope(IAnsiConsole console, Style style)
|
|
||||||
{
|
|
||||||
_console = console ?? throw new ArgumentNullException(nameof(console));
|
|
||||||
_style = style ?? throw new ArgumentNullException(nameof(style));
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")]
|
|
||||||
[SuppressMessage("Performance", "CA1821:Remove empty Finalizers")]
|
|
||||||
~StyleScope()
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Style scope was not disposed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
_console.SetColor(_style.Foreground, true);
|
|
||||||
_console.SetColor(_style.Background, false);
|
|
||||||
_console.Decoration = _style.Decoration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class ColorScope : IDisposable
|
|
||||||
{
|
|
||||||
private readonly IAnsiConsole _console;
|
|
||||||
private readonly Color _color;
|
|
||||||
private readonly bool _foreground;
|
|
||||||
|
|
||||||
public ColorScope(IAnsiConsole console, Color color, bool foreground)
|
|
||||||
{
|
|
||||||
_console = console ?? throw new ArgumentNullException(nameof(console));
|
|
||||||
_color = color;
|
|
||||||
_foreground = foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")]
|
|
||||||
[SuppressMessage("Performance", "CA1821:Remove empty Finalizers")]
|
|
||||||
~ColorScope()
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Color scope was not disposed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
_console.SetColor(_color, _foreground);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class DecorationScope : IDisposable
|
|
||||||
{
|
|
||||||
private readonly IAnsiConsole _console;
|
|
||||||
private readonly Decoration _decoration;
|
|
||||||
|
|
||||||
public DecorationScope(IAnsiConsole console, Decoration decoration)
|
|
||||||
{
|
|
||||||
_console = console ?? throw new ArgumentNullException(nameof(console));
|
|
||||||
_decoration = decoration;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")]
|
|
||||||
[SuppressMessage("Performance", "CA1821:Remove empty Finalizers")]
|
|
||||||
~DecorationScope()
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Decoration scope was not disposed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
_console.Decoration = _decoration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
namespace Spectre.Console.Internal
|
namespace Spectre.Console.Internal
|
||||||
{
|
{
|
||||||
@@ -11,9 +12,9 @@ namespace Spectre.Console.Internal
|
|||||||
private static readonly bool _alreadyNormalized
|
private static readonly bool _alreadyNormalized
|
||||||
= Environment.NewLine.Equals("\n", StringComparison.OrdinalIgnoreCase);
|
= Environment.NewLine.Equals("\n", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public static int CellLength(this string text, Encoding encoding)
|
public static int CellLength(this string text, RenderContext context)
|
||||||
{
|
{
|
||||||
return Cell.GetCellLength(encoding, text);
|
return Cell.GetCellLength(context, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string NormalizeLineEndings(this string text, bool native = false)
|
public static string NormalizeLineEndings(this string text, bool native = false)
|
||||||
@@ -78,5 +79,28 @@ namespace Spectre.Console.Internal
|
|||||||
|
|
||||||
return result.ToArray();
|
return result.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/
|
||||||
|
public static int GetDeterministicHashCode(this string str)
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
var hash1 = (5381 << 16) + 5381;
|
||||||
|
var hash2 = hash1;
|
||||||
|
|
||||||
|
for (var i = 0; i < str.Length; i += 2)
|
||||||
|
{
|
||||||
|
hash1 = ((hash1 << 5) + hash1) ^ str[i];
|
||||||
|
if (i == str.Length - 1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash1 + (hash2 * 1566083941);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,11 @@ namespace Spectre.Console.Internal
|
|||||||
{
|
{
|
||||||
internal sealed class FallbackConsoleRenderer : IAnsiConsole
|
internal sealed class FallbackConsoleRenderer : IAnsiConsole
|
||||||
{
|
{
|
||||||
private readonly ConsoleColor _defaultForeground;
|
|
||||||
private readonly ConsoleColor _defaultBackground;
|
|
||||||
|
|
||||||
private readonly TextWriter _out;
|
private readonly TextWriter _out;
|
||||||
private readonly ColorSystem _system;
|
private readonly ColorSystem _system;
|
||||||
private ConsoleColor _foreground;
|
private Style? _lastStyle;
|
||||||
private ConsoleColor _background;
|
|
||||||
|
|
||||||
public Capabilities Capabilities { get; }
|
public Capabilities Capabilities { get; }
|
||||||
|
|
||||||
public Encoding Encoding { get; }
|
public Encoding Encoding { get; }
|
||||||
|
|
||||||
public int Width
|
public int Width
|
||||||
@@ -44,73 +39,58 @@ namespace Spectre.Console.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Decoration Decoration { get; set; }
|
public FallbackConsoleRenderer(TextWriter @out, Capabilities capabilities)
|
||||||
|
|
||||||
public Color Foreground
|
|
||||||
{
|
{
|
||||||
get => _foreground;
|
if (capabilities == null)
|
||||||
set
|
|
||||||
{
|
{
|
||||||
_foreground = Color.ToConsoleColor(value);
|
throw new ArgumentNullException(nameof(capabilities));
|
||||||
if (_system != ColorSystem.NoColors && _out.IsStandardOut())
|
|
||||||
{
|
|
||||||
if ((int)_foreground == -1)
|
|
||||||
{
|
|
||||||
_foreground = _defaultForeground;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Console.ForegroundColor = _foreground;
|
_out = @out ?? throw new ArgumentNullException(nameof(@out));
|
||||||
}
|
_system = capabilities.ColorSystem;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color Background
|
|
||||||
{
|
|
||||||
get => _background;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_background = Color.ToConsoleColor(value);
|
|
||||||
if (_system != ColorSystem.NoColors && _out.IsStandardOut())
|
|
||||||
{
|
|
||||||
if ((int)_background == -1)
|
|
||||||
{
|
|
||||||
_background = _defaultBackground;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_system != ColorSystem.NoColors)
|
|
||||||
{
|
|
||||||
System.Console.BackgroundColor = _background;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public FallbackConsoleRenderer(TextWriter @out, ColorSystem system, bool legacyConsole)
|
|
||||||
{
|
|
||||||
_out = @out;
|
|
||||||
_system = system;
|
|
||||||
|
|
||||||
if (_out.IsStandardOut())
|
if (_out.IsStandardOut())
|
||||||
{
|
{
|
||||||
_defaultForeground = System.Console.ForegroundColor;
|
|
||||||
_defaultBackground = System.Console.BackgroundColor;
|
|
||||||
|
|
||||||
Encoding = System.Console.OutputEncoding;
|
Encoding = System.Console.OutputEncoding;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_defaultForeground = ConsoleColor.Gray;
|
|
||||||
_defaultBackground = ConsoleColor.Black;
|
|
||||||
|
|
||||||
Encoding = Encoding.UTF8;
|
Encoding = Encoding.UTF8;
|
||||||
}
|
}
|
||||||
|
|
||||||
Capabilities = new Capabilities(false, _system, legacyConsole);
|
Capabilities = capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(string text)
|
public void Write(string text, Style style)
|
||||||
{
|
{
|
||||||
|
if (_lastStyle?.Equals(style) != true)
|
||||||
|
{
|
||||||
|
SetStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
_out.Write(text.NormalizeLineEndings(native: true));
|
_out.Write(text.NormalizeLineEndings(native: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetStyle(Style style)
|
||||||
|
{
|
||||||
|
_lastStyle = style;
|
||||||
|
|
||||||
|
if (_out.IsStandardOut())
|
||||||
|
{
|
||||||
|
System.Console.ResetColor();
|
||||||
|
|
||||||
|
var background = Color.ToConsoleColor(style.Background);
|
||||||
|
if (_system != ColorSystem.NoColors && _out.IsStandardOut() && (int)background != -1)
|
||||||
|
{
|
||||||
|
System.Console.BackgroundColor = background;
|
||||||
|
}
|
||||||
|
|
||||||
|
var foreground = Color.ToConsoleColor(style.Foreground);
|
||||||
|
if (_system != ColorSystem.NoColors && _out.IsStandardOut() && (int)foreground != -1)
|
||||||
|
{
|
||||||
|
System.Console.ForegroundColor = foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/Spectre.Console/Internal/LinkIdentityGenerator.cs
Normal file
31
src/Spectre.Console/Internal/LinkIdentityGenerator.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Spectre.Console.Internal
|
||||||
|
{
|
||||||
|
internal sealed class LinkIdentityGenerator : ILinkIdentityGenerator
|
||||||
|
{
|
||||||
|
private readonly Random _random;
|
||||||
|
|
||||||
|
public LinkIdentityGenerator()
|
||||||
|
{
|
||||||
|
_random = new Random(DateTime.Now.Millisecond);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GenerateId(string link, string text)
|
||||||
|
{
|
||||||
|
if (link is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(link));
|
||||||
|
}
|
||||||
|
|
||||||
|
link += text ?? string.Empty;
|
||||||
|
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
return Math.Abs(
|
||||||
|
link.GetHashCode() +
|
||||||
|
_random.Next(0, int.MaxValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,155 +1,28 @@
|
|||||||
// Taken and modified from NStack project by Miguel de Icaza, licensed under BSD-3
|
|
||||||
// https://github.com/migueldeicaza/NStack/blob/3fc024fb2c2e99927d3e12991570fb54db8ce01e/NStack/unicode/Rune.ColumnWidth.cs
|
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using Spectre.Console.Rendering;
|
||||||
|
using Wcwidth;
|
||||||
|
|
||||||
namespace Spectre.Console.Internal
|
namespace Spectre.Console.Internal
|
||||||
{
|
{
|
||||||
internal static class Cell
|
internal static class Cell
|
||||||
{
|
{
|
||||||
[SuppressMessage("Design", "RCS1169:Make field read-only.")]
|
public static int GetCellLength(RenderContext context, string text)
|
||||||
[SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line")]
|
|
||||||
private static readonly uint[,] _combining = new uint[,]
|
|
||||||
{
|
{
|
||||||
{ 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
|
return text.Sum(rune =>
|
||||||
{ 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
|
|
||||||
{ 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
|
|
||||||
{ 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
|
|
||||||
{ 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
|
|
||||||
{ 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
|
|
||||||
{ 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
|
|
||||||
{ 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
|
|
||||||
{ 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
|
|
||||||
{ 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
|
|
||||||
{ 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
|
|
||||||
{ 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
|
|
||||||
{ 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
|
|
||||||
{ 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
|
|
||||||
{ 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
|
|
||||||
{ 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
|
|
||||||
{ 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
|
|
||||||
{ 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
|
|
||||||
{ 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
|
|
||||||
{ 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
|
|
||||||
{ 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
|
|
||||||
{ 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
|
|
||||||
{ 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
|
|
||||||
{ 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
|
|
||||||
{ 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
|
|
||||||
{ 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
|
|
||||||
{ 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
|
|
||||||
{ 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
|
|
||||||
{ 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
|
|
||||||
{ 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
|
|
||||||
{ 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
|
|
||||||
{ 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
|
|
||||||
{ 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
|
|
||||||
{ 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
|
|
||||||
{ 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
|
|
||||||
{ 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
|
|
||||||
{ 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
|
|
||||||
{ 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
|
|
||||||
{ 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
|
|
||||||
{ 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
|
|
||||||
{ 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
|
|
||||||
{ 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
|
|
||||||
{ 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
|
|
||||||
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
|
|
||||||
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
|
|
||||||
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
|
|
||||||
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
|
|
||||||
{ 0xE0100, 0xE01EF },
|
|
||||||
};
|
|
||||||
|
|
||||||
public static int GetCellLength(Encoding encoding, string text)
|
|
||||||
{
|
{
|
||||||
return text.Sum(c => GetCellLength(encoding, c));
|
if (context.LegacyConsole)
|
||||||
}
|
|
||||||
|
|
||||||
public static int GetCellLength(Encoding encoding, char rune)
|
|
||||||
{
|
{
|
||||||
if (rune == '\r' || rune == '\n')
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it represented by a single byte?
|
// Is it represented by a single byte?
|
||||||
// In that case we don't have to calculate the
|
// In that case we don't have to calculate the
|
||||||
// actual cell width.
|
// actual cell width.
|
||||||
if (encoding.GetByteCount(new[] { rune }) == 1)
|
if (context.Encoding.GetByteCount(new[] { rune }) == 1)
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var irune = (uint)rune;
|
|
||||||
if (irune < 32)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (irune < 127)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (irune >= 0x7f && irune <= 0xa0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Binary search in table of non-spacing characters
|
|
||||||
if (BinarySearch(irune, _combining, _combining.GetLength(0) - 1) != 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we arrive here, ucs is not a combining or C0/C1 control character
|
|
||||||
return 1 +
|
|
||||||
((irune >= 0x1100 &&
|
|
||||||
(irune <= 0x115f || /* Hangul Jamo init. consonants */
|
|
||||||
irune == 0x2329 || irune == 0x232a ||
|
|
||||||
(irune >= 0x2e80 && irune <= 0xa4cf &&
|
|
||||||
irune != 0x303f) || /* CJK ... Yi */
|
|
||||||
(irune >= 0xac00 && irune <= 0xd7a3) || /* Hangul Syllables */
|
|
||||||
(irune >= 0xf900 && irune <= 0xfaff) || /* CJK Compatibility Ideographs */
|
|
||||||
(irune >= 0xfe10 && irune <= 0xfe19) || /* Vertical forms */
|
|
||||||
(irune >= 0xfe30 && irune <= 0xfe6f) || /* CJK Compatibility Forms */
|
|
||||||
(irune >= 0xff00 && irune <= 0xff60) || /* Fullwidth Forms */
|
|
||||||
(irune >= 0xffe0 && irune <= 0xffe6) ||
|
|
||||||
(irune >= 0x20000 && irune <= 0x2fffd) ||
|
|
||||||
(irune >= 0x30000 && irune <= 0x3fffd))) ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int BinarySearch(uint rune, uint[,] table, int max)
|
|
||||||
{
|
|
||||||
var min = 0;
|
|
||||||
int mid;
|
|
||||||
|
|
||||||
if (rune < table[0, 0] || rune > table[max, 1])
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (max >= min)
|
|
||||||
{
|
|
||||||
mid = (min + max) / 2;
|
|
||||||
if (rune > table[mid, 1])
|
|
||||||
{
|
|
||||||
min = mid + 1;
|
|
||||||
}
|
|
||||||
else if (rune < table[mid, 0])
|
|
||||||
{
|
|
||||||
max = mid - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return UnicodeCalculator.GetWidth(rune);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ namespace Spectre.Console.Internal
|
|||||||
{
|
{
|
||||||
public static Paragraph Parse(string text, Style? style = null)
|
public static Paragraph Parse(string text, Style? style = null)
|
||||||
{
|
{
|
||||||
|
if (text is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(text));
|
||||||
|
}
|
||||||
|
|
||||||
style ??= Style.Plain;
|
style ??= Style.Plain;
|
||||||
|
|
||||||
var result = new Paragraph();
|
var result = new Paragraph();
|
||||||
@@ -41,7 +46,7 @@ namespace Spectre.Console.Internal
|
|||||||
{
|
{
|
||||||
// Get the effecive style.
|
// Get the effecive style.
|
||||||
var effectiveStyle = style.Combine(stack.Reverse());
|
var effectiveStyle = style.Combine(stack.Reverse());
|
||||||
result.Append(token.Value, effectiveStyle);
|
result.Append(Emoji.Replace(token.Value), effectiveStyle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace Spectre.Console.Internal
|
|||||||
var effectiveDecoration = (Decoration?)null;
|
var effectiveDecoration = (Decoration?)null;
|
||||||
var effectiveForeground = (Color?)null;
|
var effectiveForeground = (Color?)null;
|
||||||
var effectiveBackground = (Color?)null;
|
var effectiveBackground = (Color?)null;
|
||||||
|
var effectiveLink = (string?)null;
|
||||||
|
|
||||||
var parts = text.Split(new[] { ' ' });
|
var parts = text.Split(new[] { ' ' });
|
||||||
var foreground = true;
|
var foreground = true;
|
||||||
@@ -51,6 +52,23 @@ namespace Spectre.Console.Internal
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (part.StartsWith("link=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
if (effectiveLink != null)
|
||||||
|
{
|
||||||
|
error = "A link has already been set.";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
effectiveLink = part.Substring(5);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (part.StartsWith("link", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
effectiveLink = Constants.EmptyLink;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var decoration = DecorationTable.GetDecoration(part);
|
var decoration = DecorationTable.GetDecoration(part);
|
||||||
if (decoration != null)
|
if (decoration != null)
|
||||||
{
|
{
|
||||||
@@ -116,7 +134,11 @@ namespace Spectre.Console.Internal
|
|||||||
}
|
}
|
||||||
|
|
||||||
error = null;
|
error = null;
|
||||||
return new Style(effectiveForeground, effectiveBackground, effectiveDecoration);
|
return new Style(
|
||||||
|
effectiveForeground,
|
||||||
|
effectiveBackground,
|
||||||
|
effectiveDecoration,
|
||||||
|
effectiveLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:Do not catch general exception types")]
|
[SuppressMessage("Design", "CA1031:Do not catch general exception types")]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System;
|
|||||||
namespace Spectre.Console
|
namespace Spectre.Console
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a measurement.
|
/// Represents padding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct Padding : IEquatable<Padding>
|
public struct Padding : IEquatable<Padding>
|
||||||
{
|
{
|
||||||
@@ -12,20 +12,53 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int Left { get; }
|
public int Left { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the top padding.
|
||||||
|
/// </summary>
|
||||||
|
public int Top { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the right padding.
|
/// Gets the right padding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Right { get; }
|
public int Right { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the bottom padding.
|
||||||
|
/// </summary>
|
||||||
|
public int Bottom { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Padding"/> struct.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="size">The padding for all sides.</param>
|
||||||
|
public Padding(int size)
|
||||||
|
: this(size, size, size, size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Padding"/> struct.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="horizontal">The left and right padding.</param>
|
||||||
|
/// <param name="vertical">The top and bottom padding.</param>
|
||||||
|
public Padding(int horizontal, int vertical)
|
||||||
|
: this(horizontal, vertical, horizontal, vertical)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Padding"/> struct.
|
/// Initializes a new instance of the <see cref="Padding"/> struct.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="left">The left padding.</param>
|
/// <param name="left">The left padding.</param>
|
||||||
|
/// <param name="top">The top padding.</param>
|
||||||
/// <param name="right">The right padding.</param>
|
/// <param name="right">The right padding.</param>
|
||||||
public Padding(int left, int right)
|
/// <param name="bottom">The bottom padding.</param>
|
||||||
|
public Padding(int left, int top, int right, int bottom)
|
||||||
{
|
{
|
||||||
Left = left;
|
Left = left;
|
||||||
|
Top = top;
|
||||||
Right = right;
|
Right = right;
|
||||||
|
Bottom = bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@@ -41,7 +74,9 @@ namespace Spectre.Console
|
|||||||
{
|
{
|
||||||
var hash = (int)2166136261;
|
var hash = (int)2166136261;
|
||||||
hash = (hash * 16777619) ^ Left.GetHashCode();
|
hash = (hash * 16777619) ^ Left.GetHashCode();
|
||||||
|
hash = (hash * 16777619) ^ Top.GetHashCode();
|
||||||
hash = (hash * 16777619) ^ Right.GetHashCode();
|
hash = (hash * 16777619) ^ Right.GetHashCode();
|
||||||
|
hash = (hash * 16777619) ^ Bottom.GetHashCode();
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +84,10 @@ namespace Spectre.Console
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool Equals(Padding other)
|
public bool Equals(Padding other)
|
||||||
{
|
{
|
||||||
return Left == other.Left && Right == other.Right;
|
return Left == other.Left
|
||||||
|
&& Top == other.Top
|
||||||
|
&& Right == other.Right
|
||||||
|
&& Bottom == other.Bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -75,12 +113,21 @@ namespace Spectre.Console
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the horizontal padding.
|
/// Gets the padding width.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The horizontal padding.</returns>
|
/// <returns>The padding width.</returns>
|
||||||
public int GetHorizontalPadding()
|
public int GetWidth()
|
||||||
{
|
{
|
||||||
return Left + Right;
|
return Left + Right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the padding height.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The padding height.</returns>
|
||||||
|
public int GetHeight()
|
||||||
|
{
|
||||||
|
return Top + Bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using Spectre.Console.Internal;
|
using Spectre.Console.Internal;
|
||||||
|
|
||||||
namespace Spectre.Console.Rendering
|
namespace Spectre.Console.Rendering
|
||||||
@@ -82,11 +81,11 @@ namespace Spectre.Console.Rendering
|
|||||||
/// Gets the number of cells that this segment
|
/// Gets the number of cells that this segment
|
||||||
/// occupies in the console.
|
/// occupies in the console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="encoding">The encoding to use.</param>
|
/// <param name="context">The render context.</param>
|
||||||
/// <returns>The number of cells that this segment occupies in the console.</returns>
|
/// <returns>The number of cells that this segment occupies in the console.</returns>
|
||||||
public int CellLength(Encoding encoding)
|
public int CellLength(RenderContext context)
|
||||||
{
|
{
|
||||||
return Text.CellLength(encoding);
|
return Text.CellLength(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -266,17 +265,17 @@ namespace Spectre.Console.Rendering
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="segment">The segment to split.</param>
|
/// <param name="segment">The segment to split.</param>
|
||||||
/// <param name="overflow">The overflow strategy to use.</param>
|
/// <param name="overflow">The overflow strategy to use.</param>
|
||||||
/// <param name="encoding">The encoding to use.</param>
|
/// <param name="context">The render context.</param>
|
||||||
/// <param name="width">The maximum width.</param>
|
/// <param name="width">The maximum width.</param>
|
||||||
/// <returns>A list of segments that has been split.</returns>
|
/// <returns>A list of segments that has been split.</returns>
|
||||||
public static List<Segment> SplitOverflow(Segment segment, Overflow? overflow, Encoding encoding, int width)
|
public static List<Segment> SplitOverflow(Segment segment, Overflow? overflow, RenderContext context, int width)
|
||||||
{
|
{
|
||||||
if (segment is null)
|
if (segment is null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(segment));
|
throw new ArgumentNullException(nameof(segment));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segment.CellLength(encoding) <= width)
|
if (segment.CellLength(context) <= width)
|
||||||
{
|
{
|
||||||
return new List<Segment>(1) { segment };
|
return new List<Segment>(1) { segment };
|
||||||
}
|
}
|
||||||
@@ -288,7 +287,7 @@ namespace Spectre.Console.Rendering
|
|||||||
|
|
||||||
if (overflow == Overflow.Fold)
|
if (overflow == Overflow.Fold)
|
||||||
{
|
{
|
||||||
var totalLength = segment.Text.CellLength(encoding);
|
var totalLength = segment.Text.CellLength(context);
|
||||||
var lengthLeft = totalLength;
|
var lengthLeft = totalLength;
|
||||||
while (lengthLeft > 0)
|
while (lengthLeft > 0)
|
||||||
{
|
{
|
||||||
@@ -311,12 +310,12 @@ namespace Spectre.Console.Rendering
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Segment TruncateWithEllipsis(string text, Style style, Encoding encoding, int maxWidth)
|
internal static Segment TruncateWithEllipsis(string text, Style style, RenderContext context, int maxWidth)
|
||||||
{
|
{
|
||||||
return SplitOverflow(
|
return SplitOverflow(
|
||||||
new Segment(text, style),
|
new Segment(text, style),
|
||||||
Overflow.Ellipsis,
|
Overflow.Ellipsis,
|
||||||
encoding,
|
context,
|
||||||
maxWidth)[0];
|
maxWidth)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Spectre.Console.Rendering
|
namespace Spectre.Console.Rendering
|
||||||
{
|
{
|
||||||
@@ -19,11 +18,11 @@ namespace Spectre.Console.Rendering
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the cell width of the segment line.
|
/// Gets the cell width of the segment line.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="encoding">The encoding to use.</param>
|
/// <param name="context">The render context.</param>
|
||||||
/// <returns>The cell width of the segment line.</returns>
|
/// <returns>The cell width of the segment line.</returns>
|
||||||
public int CellWidth(Encoding encoding)
|
public int CellWidth(RenderContext context)
|
||||||
{
|
{
|
||||||
return this.Sum(line => line.CellLength(encoding));
|
return this.Sum(line => line.CellLength(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="..\stylecop.json" Link="stylecop.json" />
|
<AdditionalFiles Include="..\stylecop.json" Link="Properties/stylecop.json" />
|
||||||
<None Include="../../resources/gfx/small-logo.png" Pack="true" PackagePath="\" Link="Properties/small-logo.png" />
|
<None Include="../../resources/gfx/small-logo.png" Pack="true" PackagePath="\" Link="Properties/small-logo.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@@ -20,6 +20,9 @@
|
|||||||
<Compile Update="Border.*.cs">
|
<Compile Update="Border.*.cs">
|
||||||
<DependentUpon>Border.cs</DependentUpon>
|
<DependentUpon>Border.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Update="Emoji.*.cs">
|
||||||
|
<DependentUpon>Emoji.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Update="Extensions/AnsiConsoleExtensions.*.cs">
|
<Compile Update="Extensions/AnsiConsoleExtensions.*.cs">
|
||||||
<DependentUpon>Extensions/AnsiConsoleExtensions.cs</DependentUpon>
|
<DependentUpon>Extensions/AnsiConsoleExtensions.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -32,6 +35,7 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Wcwidth" Version="0.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -41,12 +45,6 @@
|
|||||||
<Compile Update="Extensions\AnsiConsoleExtensions.Rendering.cs">
|
<Compile Update="Extensions\AnsiConsoleExtensions.Rendering.cs">
|
||||||
<DependentUpon>AnsiConsoleExtensions.cs</DependentUpon>
|
<DependentUpon>AnsiConsoleExtensions.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Update="Extensions\AnsiConsoleExtensions.Write.cs">
|
|
||||||
<DependentUpon>AnsiConsoleExtensions.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Extensions\AnsiConsoleExtensions.WriteLine.cs">
|
|
||||||
<DependentUpon>AnsiConsoleExtensions.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AnnotatedReferenceAssemblyVersion>3.0.0</AnnotatedReferenceAssemblyVersion>
|
<AnnotatedReferenceAssemblyVersion>3.0.0</AnnotatedReferenceAssemblyVersion>
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Decoration Decoration { get; }
|
public Decoration Decoration { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the link.
|
||||||
|
/// </summary>
|
||||||
|
public string? Link { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an <see cref="Style"/> with the
|
/// Gets an <see cref="Style"/> with the
|
||||||
/// default colors and without text decoration.
|
/// default colors and without text decoration.
|
||||||
@@ -31,7 +36,7 @@ namespace Spectre.Console
|
|||||||
public static Style Plain { get; } = new Style();
|
public static Style Plain { get; } = new Style();
|
||||||
|
|
||||||
private Style()
|
private Style()
|
||||||
: this(null, null, null)
|
: this(null, null, null, null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,11 +46,13 @@ namespace Spectre.Console
|
|||||||
/// <param name="foreground">The foreground color.</param>
|
/// <param name="foreground">The foreground color.</param>
|
||||||
/// <param name="background">The background color.</param>
|
/// <param name="background">The background color.</param>
|
||||||
/// <param name="decoration">The text decoration.</param>
|
/// <param name="decoration">The text decoration.</param>
|
||||||
public Style(Color? foreground = null, Color? background = null, Decoration? decoration = null)
|
/// <param name="link">The link.</param>
|
||||||
|
public Style(Color? foreground = null, Color? background = null, Decoration? decoration = null, string? link = null)
|
||||||
{
|
{
|
||||||
Foreground = foreground ?? Color.Default;
|
Foreground = foreground ?? Color.Default;
|
||||||
Background = background ?? Color.Default;
|
Background = background ?? Color.Default;
|
||||||
Decoration = decoration ?? Decoration.None;
|
Decoration = decoration ?? Decoration.None;
|
||||||
|
Link = link;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -78,13 +85,23 @@ namespace Spectre.Console
|
|||||||
return new Style(decoration: decoration);
|
return new Style(decoration: decoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new style from the specified link.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="link">The link.</param>
|
||||||
|
/// <returns>A new <see cref="Style"/> with the specified link.</returns>
|
||||||
|
public static Style WithLink(string link)
|
||||||
|
{
|
||||||
|
return new Style(link: link);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a copy of the current <see cref="Style"/>.
|
/// Creates a copy of the current <see cref="Style"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A copy of the current <see cref="Style"/>.</returns>
|
/// <returns>A copy of the current <see cref="Style"/>.</returns>
|
||||||
public Style Clone()
|
public Style Clone()
|
||||||
{
|
{
|
||||||
return new Style(Foreground, Background, Decoration);
|
return new Style(Foreground, Background, Decoration, Link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -111,7 +128,13 @@ namespace Spectre.Console
|
|||||||
background = other.Background;
|
background = other.Background;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Style(foreground, background, Decoration | other.Decoration);
|
var link = Link;
|
||||||
|
if (!string.IsNullOrWhiteSpace(other.Link))
|
||||||
|
{
|
||||||
|
link = other.Link;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Style(foreground, background, Decoration | other.Decoration, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -158,6 +181,12 @@ namespace Spectre.Console
|
|||||||
hash = (hash * 16777619) ^ Foreground.GetHashCode();
|
hash = (hash * 16777619) ^ Foreground.GetHashCode();
|
||||||
hash = (hash * 16777619) ^ Background.GetHashCode();
|
hash = (hash * 16777619) ^ Background.GetHashCode();
|
||||||
hash = (hash * 16777619) ^ Decoration.GetHashCode();
|
hash = (hash * 16777619) ^ Decoration.GetHashCode();
|
||||||
|
|
||||||
|
if (Link != null)
|
||||||
|
{
|
||||||
|
hash = (hash * 16777619) ^ Link?.GetHashCode() ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +207,8 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
return Foreground.Equals(other.Foreground) &&
|
return Foreground.Equals(other.Foreground) &&
|
||||||
Background.Equals(other.Background) &&
|
Background.Equals(other.Background) &&
|
||||||
Decoration == other.Decoration;
|
Decoration == other.Decoration &&
|
||||||
|
string.Equals(Link, other.Link, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Spectre.Console
|
|||||||
private readonly List<IRenderable> _items;
|
private readonly List<IRenderable> _items;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Padding Padding { get; set; } = new Padding(0, 1);
|
public Padding Padding { get; set; } = new Padding(0, 0, 1, 0);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether or not the columns should
|
/// Gets or sets a value indicating whether or not the columns should
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the padding of the column.
|
/// Gets or sets the padding of the column.
|
||||||
|
/// Vertical padding (top and bottom) is ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Padding Padding
|
public Padding Padding
|
||||||
{
|
{
|
||||||
@@ -48,7 +49,7 @@ namespace Spectre.Console
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public GridColumn()
|
public GridColumn()
|
||||||
{
|
{
|
||||||
_padding = new Padding(0, 2);
|
_padding = new Padding(0, 0, 2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
106
src/Spectre.Console/Widgets/Padder.cs
Normal file
106
src/Spectre.Console/Widgets/Padder.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Spectre.Console.Internal;
|
||||||
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
|
namespace Spectre.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents padding around a <see cref="IRenderable"/> object.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class Padder : Renderable, IPaddable, IExpandable
|
||||||
|
{
|
||||||
|
private readonly IRenderable _child;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public Padding Padding { get; set; } = new Padding(1, 1, 1, 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether or not the padding should
|
||||||
|
/// fit the available space. If <c>false</c>, the padding width will be
|
||||||
|
/// auto calculated. Defaults to <c>false</c>.
|
||||||
|
/// </summary>
|
||||||
|
public bool Expand { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Padder"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="child">The thing to pad.</param>
|
||||||
|
/// <param name="padding">The padding. Defaults to <c>1,1,1,1</c> if null.</param>
|
||||||
|
public Padder(IRenderable child, Padding? padding = null)
|
||||||
|
{
|
||||||
|
_child = child;
|
||||||
|
Padding = padding ?? Padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||||
|
{
|
||||||
|
var paddingWidth = Padding.GetWidth();
|
||||||
|
var measurement = _child.Measure(context, maxWidth - paddingWidth);
|
||||||
|
|
||||||
|
return new Measurement(
|
||||||
|
measurement.Min + paddingWidth,
|
||||||
|
measurement.Max + paddingWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
|
||||||
|
{
|
||||||
|
var paddingWidth = Padding.GetWidth();
|
||||||
|
var childWidth = maxWidth - paddingWidth;
|
||||||
|
|
||||||
|
if (!Expand)
|
||||||
|
{
|
||||||
|
var measurement = _child.Measure(context, maxWidth - paddingWidth);
|
||||||
|
childWidth = measurement.Max;
|
||||||
|
}
|
||||||
|
|
||||||
|
var width = childWidth + paddingWidth;
|
||||||
|
var result = new List<Segment>();
|
||||||
|
|
||||||
|
// Top padding
|
||||||
|
for (var i = 0; i < Padding.Top; i++)
|
||||||
|
{
|
||||||
|
result.Add(new Segment(new string(' ', width)));
|
||||||
|
result.Add(Segment.LineBreak);
|
||||||
|
}
|
||||||
|
|
||||||
|
var child = _child.Render(context, maxWidth - paddingWidth);
|
||||||
|
foreach (var (_, _, _, line) in Segment.SplitLines(child).Enumerate())
|
||||||
|
{
|
||||||
|
// Left padding
|
||||||
|
if (Padding.Left != 0)
|
||||||
|
{
|
||||||
|
result.Add(new Segment(new string(' ', Padding.Left)));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.AddRange(line);
|
||||||
|
|
||||||
|
// Right padding
|
||||||
|
if (Padding.Right != 0)
|
||||||
|
{
|
||||||
|
result.Add(new Segment(new string(' ', Padding.Right)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Missing space on right side?
|
||||||
|
var lineWidth = line.CellWidth(context);
|
||||||
|
var diff = width - lineWidth - Padding.Left - Padding.Right;
|
||||||
|
if (diff > 0)
|
||||||
|
{
|
||||||
|
result.Add(new Segment(new string(' ', diff)));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(Segment.LineBreak);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom padding
|
||||||
|
for (var i = 0; i < Padding.Bottom; i++)
|
||||||
|
{
|
||||||
|
result.Add(new Segment(new string(' ', width)));
|
||||||
|
result.Add(Segment.LineBreak);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ namespace Spectre.Console
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the padding.
|
/// Gets or sets the padding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Padding Padding { get; set; } = new Padding(1, 1);
|
public Padding Padding { get; set; } = new Padding(1, 0, 1, 0);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the header.
|
/// Gets or sets the header.
|
||||||
@@ -61,10 +61,11 @@ namespace Spectre.Console
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||||
{
|
{
|
||||||
var childWidth = _child.Measure(context, maxWidth);
|
var child = new Padder(_child, Padding);
|
||||||
|
var childWidth = ((IRenderable)child).Measure(context, maxWidth);
|
||||||
return new Measurement(
|
return new Measurement(
|
||||||
childWidth.Min + EdgeWidth + Padding.GetHorizontalPadding(),
|
childWidth.Min + EdgeWidth,
|
||||||
childWidth.Max + EdgeWidth + Padding.GetHorizontalPadding());
|
childWidth.Max + EdgeWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@@ -73,16 +74,16 @@ namespace Spectre.Console
|
|||||||
var border = Border.GetSafeBorder((context.LegacyConsole || !context.Unicode) && UseSafeBorder);
|
var border = Border.GetSafeBorder((context.LegacyConsole || !context.Unicode) && UseSafeBorder);
|
||||||
var borderStyle = BorderStyle ?? Style.Plain;
|
var borderStyle = BorderStyle ?? Style.Plain;
|
||||||
|
|
||||||
var paddingWidth = Padding.GetHorizontalPadding();
|
var child = new Padder(_child, Padding);
|
||||||
var childWidth = maxWidth - EdgeWidth - paddingWidth;
|
var childWidth = maxWidth - EdgeWidth;
|
||||||
|
|
||||||
if (!Expand)
|
if (!Expand)
|
||||||
{
|
{
|
||||||
var measurement = _child.Measure(context, maxWidth - EdgeWidth - paddingWidth);
|
var measurement = ((IRenderable)child).Measure(context, maxWidth - EdgeWidth);
|
||||||
childWidth = measurement.Max;
|
childWidth = measurement.Max;
|
||||||
}
|
}
|
||||||
|
|
||||||
var panelWidth = childWidth + EdgeWidth + paddingWidth;
|
var panelWidth = childWidth + EdgeWidth;
|
||||||
panelWidth = Math.Min(panelWidth, maxWidth);
|
panelWidth = Math.Min(panelWidth, maxWidth);
|
||||||
|
|
||||||
var result = new List<Segment>();
|
var result = new List<Segment>();
|
||||||
@@ -91,22 +92,16 @@ namespace Spectre.Console
|
|||||||
AddTopBorder(result, context, border, borderStyle, panelWidth);
|
AddTopBorder(result, context, border, borderStyle, panelWidth);
|
||||||
|
|
||||||
// Split the child segments into lines.
|
// Split the child segments into lines.
|
||||||
var childSegments = _child.Render(context, childWidth);
|
var childSegments = ((IRenderable)child).Render(context, childWidth);
|
||||||
foreach (var line in Segment.SplitLines(childSegments, panelWidth))
|
foreach (var line in Segment.SplitLines(childSegments, panelWidth))
|
||||||
{
|
{
|
||||||
result.Add(new Segment(border.GetPart(BorderPart.CellLeft), borderStyle));
|
result.Add(new Segment(border.GetPart(BorderPart.CellLeft), borderStyle));
|
||||||
|
|
||||||
// Left padding
|
|
||||||
if (Padding.Left > 0)
|
|
||||||
{
|
|
||||||
result.Add(new Segment(new string(' ', Padding.Left)));
|
|
||||||
}
|
|
||||||
|
|
||||||
var content = new List<Segment>();
|
var content = new List<Segment>();
|
||||||
content.AddRange(line);
|
content.AddRange(line);
|
||||||
|
|
||||||
// Do we need to pad the panel?
|
// Do we need to pad the panel?
|
||||||
var length = line.Sum(segment => segment.CellLength(context.Encoding));
|
var length = line.Sum(segment => segment.CellLength(context));
|
||||||
if (length < childWidth)
|
if (length < childWidth)
|
||||||
{
|
{
|
||||||
var diff = childWidth - length;
|
var diff = childWidth - length;
|
||||||
@@ -115,12 +110,6 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
result.AddRange(content);
|
result.AddRange(content);
|
||||||
|
|
||||||
// Right padding
|
|
||||||
if (Padding.Right > 0)
|
|
||||||
{
|
|
||||||
result.Add(new Segment(new string(' ', Padding.Right)));
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Add(new Segment(border.GetPart(BorderPart.CellRight), borderStyle));
|
result.Add(new Segment(border.GetPart(BorderPart.CellRight), borderStyle));
|
||||||
result.Add(Segment.LineBreak);
|
result.Add(Segment.LineBreak);
|
||||||
}
|
}
|
||||||
@@ -149,9 +138,9 @@ namespace Spectre.Console
|
|||||||
var rightSpacing = 0;
|
var rightSpacing = 0;
|
||||||
|
|
||||||
var headerWidth = panelWidth - (EdgeWidth * 2);
|
var headerWidth = panelWidth - (EdgeWidth * 2);
|
||||||
var header = Segment.TruncateWithEllipsis(Header.Text, Header.Style ?? borderStyle, context.Encoding, headerWidth);
|
var header = Segment.TruncateWithEllipsis(Header.Text, Header.Style ?? borderStyle, context, headerWidth);
|
||||||
|
|
||||||
var excessWidth = headerWidth - header.CellLength(context.Encoding);
|
var excessWidth = headerWidth - header.CellLength(context);
|
||||||
if (excessWidth > 0)
|
if (excessWidth > 0)
|
||||||
{
|
{
|
||||||
switch (Header.Alignment ?? Justify.Left)
|
switch (Header.Alignment ?? Justify.Left)
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ namespace Spectre.Console
|
|||||||
return new Measurement(0, 0);
|
return new Measurement(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var min = _lines.Max(line => line.Max(segment => segment.CellLength(context.Encoding)));
|
var min = _lines.Max(line => line.Max(segment => segment.CellLength(context)));
|
||||||
var max = _lines.Max(x => x.CellWidth(context.Encoding));
|
var max = _lines.Max(x => x.CellWidth(context));
|
||||||
|
|
||||||
return new Measurement(min, Math.Min(max, maxWidth));
|
return new Measurement(min, Math.Min(max, maxWidth));
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ namespace Spectre.Console
|
|||||||
var justification = context.Justification ?? Alignment ?? Justify.Left;
|
var justification = context.Justification ?? Alignment ?? Justify.Left;
|
||||||
foreach (var (_, _, last, line) in lines.Enumerate())
|
foreach (var (_, _, last, line) in lines.Enumerate())
|
||||||
{
|
{
|
||||||
var length = line.Sum(l => l.StripLineEndings().CellLength(context.Encoding));
|
var length = line.Sum(l => l.StripLineEndings().CellLength(context));
|
||||||
if (length < maxWidth)
|
if (length < maxWidth)
|
||||||
{
|
{
|
||||||
// Justify right side
|
// Justify right side
|
||||||
@@ -193,7 +193,7 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
private List<SegmentLine> SplitLines(RenderContext context, int maxWidth)
|
private List<SegmentLine> SplitLines(RenderContext context, int maxWidth)
|
||||||
{
|
{
|
||||||
if (_lines.Max(x => x.CellWidth(context.Encoding)) <= maxWidth)
|
if (_lines.Max(x => x.CellWidth(context)) <= maxWidth)
|
||||||
{
|
{
|
||||||
return Clone();
|
return Clone();
|
||||||
}
|
}
|
||||||
@@ -244,15 +244,15 @@ namespace Spectre.Console
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var length = current.CellLength(context.Encoding);
|
var length = current.CellLength(context);
|
||||||
if (length > maxWidth)
|
if (length > maxWidth)
|
||||||
{
|
{
|
||||||
// The current segment is longer than the width of the console,
|
// The current segment is longer than the width of the console,
|
||||||
// so we will need to crop it up, into new segments.
|
// so we will need to crop it up, into new segments.
|
||||||
var segments = Segment.SplitOverflow(current, Overflow, context.Encoding, maxWidth);
|
var segments = Segment.SplitOverflow(current, Overflow, context, maxWidth);
|
||||||
if (segments.Count > 0)
|
if (segments.Count > 0)
|
||||||
{
|
{
|
||||||
if (line.CellWidth(context.Encoding) + segments[0].CellLength(context.Encoding) > maxWidth)
|
if (line.CellWidth(context) + segments[0].CellLength(context) > maxWidth)
|
||||||
{
|
{
|
||||||
lines.Add(line);
|
lines.Add(line);
|
||||||
line = new SegmentLine();
|
line = new SegmentLine();
|
||||||
@@ -272,7 +272,7 @@ namespace Spectre.Console
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (line.CellWidth(context.Encoding) + length > maxWidth)
|
if (line.CellWidth(context) + length > maxWidth)
|
||||||
{
|
{
|
||||||
line.Add(Segment.Empty);
|
line.Add(Segment.Empty);
|
||||||
lines.Add(line);
|
lines.Add(line);
|
||||||
|
|||||||
@@ -221,12 +221,12 @@ namespace Spectre.Console
|
|||||||
result.Add(Segment.LineBreak);
|
result.Add(Segment.LineBreak);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through each cell row
|
|
||||||
foreach (var cellRowIndex in Enumerable.Range(0, cellHeight))
|
|
||||||
{
|
|
||||||
// Make cells the same shape
|
// Make cells the same shape
|
||||||
cells = Segment.MakeSameHeight(cellHeight, cells);
|
cells = Segment.MakeSameHeight(cellHeight, cells);
|
||||||
|
|
||||||
|
// Iterate through each cell row
|
||||||
|
foreach (var cellRowIndex in Enumerable.Range(0, cellHeight))
|
||||||
|
{
|
||||||
foreach (var (cellIndex, firstCell, lastCell, cell) in cells.Enumerate())
|
foreach (var (cellIndex, firstCell, lastCell, cell) in cells.Enumerate())
|
||||||
{
|
{
|
||||||
if (firstCell && showBorder)
|
if (firstCell && showBorder)
|
||||||
@@ -250,7 +250,7 @@ namespace Spectre.Console
|
|||||||
result.AddRange(cell[cellRowIndex]);
|
result.AddRange(cell[cellRowIndex]);
|
||||||
|
|
||||||
// Pad cell content right
|
// Pad cell content right
|
||||||
var length = cell[cellRowIndex].Sum(segment => segment.CellLength(context.Encoding));
|
var length = cell[cellRowIndex].Sum(segment => segment.CellLength(context));
|
||||||
if (length < columnWidths[cellIndex])
|
if (length < columnWidths[cellIndex])
|
||||||
{
|
{
|
||||||
result.Add(new Segment(new string(' ', columnWidths[cellIndex] - length)));
|
result.Add(new Segment(new string(' ', columnWidths[cellIndex] - length)));
|
||||||
@@ -403,7 +403,7 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
private (int Min, int Max) MeasureColumn(TableColumn column, RenderContext options, int maxWidth)
|
private (int Min, int Max) MeasureColumn(TableColumn column, RenderContext options, int maxWidth)
|
||||||
{
|
{
|
||||||
var padding = column.Padding.GetHorizontalPadding();
|
var padding = column.Padding.GetWidth();
|
||||||
|
|
||||||
// Predetermined width?
|
// Predetermined width?
|
||||||
if (column.Width != null)
|
if (column.Width != null)
|
||||||
@@ -438,7 +438,7 @@ namespace Spectre.Console
|
|||||||
var hideBorder = !Border.Visible;
|
var hideBorder = !Border.Visible;
|
||||||
var separators = hideBorder ? 0 : _columns.Count - 1;
|
var separators = hideBorder ? 0 : _columns.Count - 1;
|
||||||
var edges = hideBorder ? 0 : EdgeCount;
|
var edges = hideBorder ? 0 : EdgeCount;
|
||||||
var padding = includePadding ? _columns.Select(x => x.Padding.GetHorizontalPadding()).Sum() : 0;
|
var padding = includePadding ? _columns.Select(x => x.Padding.GetWidth()).Sum() : 0;
|
||||||
|
|
||||||
if (!PadRightCell)
|
if (!PadRightCell)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace Spectre.Console
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the padding of the column.
|
/// Gets or sets the padding of the column.
|
||||||
|
/// Vertical padding (top and bottom) is ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Padding Padding { get; set; }
|
public Padding Padding { get; set; }
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ namespace Spectre.Console
|
|||||||
{
|
{
|
||||||
Text = renderable ?? throw new ArgumentNullException(nameof(renderable));
|
Text = renderable ?? throw new ArgumentNullException(nameof(renderable));
|
||||||
Width = null;
|
Width = null;
|
||||||
Padding = new Padding(1, 1);
|
Padding = new Padding(1, 0, 1, 0);
|
||||||
NoWrap = false;
|
NoWrap = false;
|
||||||
Alignment = null;
|
Alignment = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user