diff --git a/docs/input/appendix/borders.md b/docs/input/appendix/borders.md
index f2308bf..80aee4a 100644
--- a/docs/input/appendix/borders.md
+++ b/docs/input/appendix/borders.md
@@ -4,16 +4,30 @@ Order: 2
There is different built-in borders you can use for tables and panels.
-# Built-in borders
+# Table borders
-
+
-# Usage
+## Example
-To create a table and set it's border to `SimpleHeavy` as seen in the
-image above:
+To set a table border to `SimpleHeavy`:
```csharp
var table = new Table();
-table.Border = Border.SimpleHeavy;
+table.Border = TableBorder.SimpleHeavy;
+```
+
+---
+
+# Panel borders
+
+
+
+## Example
+
+To set a panel border to `Rounded`:
+
+```csharp
+var panel = new Panel("Hello World");
+panel.Border = BoxBorder.Rounded;
```
\ No newline at end of file
diff --git a/docs/input/assets/images/borders.png b/docs/input/assets/images/borders.png
deleted file mode 100644
index dc28d77..0000000
Binary files a/docs/input/assets/images/borders.png and /dev/null differ
diff --git a/docs/input/assets/images/borders/panel.png b/docs/input/assets/images/borders/panel.png
new file mode 100644
index 0000000..be3776f
Binary files /dev/null and b/docs/input/assets/images/borders/panel.png differ
diff --git a/docs/input/assets/images/borders/table.png b/docs/input/assets/images/borders/table.png
new file mode 100644
index 0000000..ebcf041
Binary files /dev/null and b/docs/input/assets/images/borders/table.png differ
diff --git a/examples/Borders/Program.cs b/examples/Borders/Program.cs
index 054f8e0..526d833 100644
--- a/examples/Borders/Program.cs
+++ b/examples/Borders/Program.cs
@@ -7,41 +7,83 @@ namespace Borders
{
public static void Main()
{
- var items = new[]
- {
- Create("Ascii", Border.Ascii),
- Create("Ascii2", Border.Ascii2),
- Create("AsciiDoubleHead", Border.AsciiDoubleHead),
- Create("Horizontal", Border.Horizontal),
- Create("Simple", Border.Simple),
- Create("SimpleHeavy", Border.SimpleHeavy),
- Create("Minimal", Border.Minimal),
- Create("MinimalHeavyHead", Border.MinimalHeavyHead),
- Create("MinimalDoubleHead", Border.MinimalDoubleHead),
- Create("Square", Border.Square),
- Create("Rounded", Border.Rounded),
- Create("Heavy", Border.Heavy),
- Create("HeavyEdge", Border.HeavyEdge),
- Create("HeavyHead", Border.HeavyHead),
- Create("Double", Border.Double),
- Create("DoubleEdge", Border.DoubleEdge),
- };
-
+ // Render panel borders
AnsiConsole.WriteLine();
- AnsiConsole.Render(new Columns(items).Collapse());
+ AnsiConsole.MarkupLine("[white bold underline]PANEL BORDERS[/]");
+ AnsiConsole.WriteLine();
+ RenderPanelBorders();
+
+ // Render table borders
+ AnsiConsole.WriteLine();
+ AnsiConsole.MarkupLine("[white bold underline]TABLE BORDERS[/]");
+ AnsiConsole.WriteLine();
+ RenderTableBorders();
}
- private static IRenderable Create(string name, Border border)
+ private static void RenderPanelBorders()
{
- var table = new Table().SetBorder(border);
- table.AddColumns("[yellow]Header 1[/]", "[yellow]Header 2[/]");
- table.AddRow("Cell", "Cell");
- table.AddRow("Cell", "Cell");
+ static IRenderable CreatePanel(string name, BoxBorder border)
+ {
+ return new Panel($"This is a panel with\nthe [yellow]{name}[/] border.")
+ .SetHeader($" {name} ", Style.Parse("blue"), Justify.Center)
+ .SetBorderStyle(Style.Parse("grey"))
+ .SetBorder(border);
+ }
- return new Panel(table)
- .SetHeader($" {name} ", Style.Parse("blue"), Justify.Center)
- .SetBorderStyle(Style.Parse("grey"))
- .NoBorder();
+ var items = new[]
+ {
+ CreatePanel("Ascii", BoxBorder.Ascii),
+ CreatePanel("Square", BoxBorder.Square),
+ CreatePanel("Rounded", BoxBorder.Rounded),
+ CreatePanel("Heavy", BoxBorder.Heavy),
+ CreatePanel("Double", BoxBorder.Double),
+ CreatePanel("None", BoxBorder.None),
+ };
+
+ AnsiConsole.Render(
+ new Padder(
+ new Columns(items).PadRight(2),
+ new Padding(2,0,0,0)));
+ }
+
+ private static void RenderTableBorders()
+ {
+ static IRenderable CreateTable(string name, TableBorder border)
+ {
+ var table = new Table().SetBorder(border);
+ table.AddColumn("[yellow]Header 1[/]");
+ table.AddColumn("[yellow]Header 2[/]", col => col.RightAligned());
+ table.AddRow("Cell", "Cell");
+ table.AddRow("Cell", "Cell");
+
+ return new Panel(table)
+ .SetHeader($" {name} ", Style.Parse("blue"), Justify.Center)
+ .SetBorderStyle(Style.Parse("grey"))
+ .NoBorder();
+ }
+
+ var items = new[]
+ {
+ CreateTable("Ascii", TableBorder.Ascii),
+ CreateTable("Ascii2", TableBorder.Ascii2),
+ CreateTable("AsciiDoubleHead", TableBorder.AsciiDoubleHead),
+ CreateTable("Horizontal", TableBorder.Horizontal),
+ CreateTable("Simple", TableBorder.Simple),
+ CreateTable("SimpleHeavy", TableBorder.SimpleHeavy),
+ CreateTable("Minimal", TableBorder.Minimal),
+ CreateTable("MinimalHeavyHead", TableBorder.MinimalHeavyHead),
+ CreateTable("MinimalDoubleHead", TableBorder.MinimalDoubleHead),
+ CreateTable("Square", TableBorder.Square),
+ CreateTable("Rounded", TableBorder.Rounded),
+ CreateTable("Heavy", TableBorder.Heavy),
+ CreateTable("HeavyEdge", TableBorder.HeavyEdge),
+ CreateTable("HeavyHead", TableBorder.HeavyHead),
+ CreateTable("Double", TableBorder.Double),
+ CreateTable("DoubleEdge", TableBorder.DoubleEdge),
+ CreateTable("Markdown", TableBorder.Markdown),
+ };
+
+ AnsiConsole.Render(new Columns(items).Collapse());
}
}
}
diff --git a/examples/Emojis/Program.cs b/examples/Emojis/Program.cs
index 87b0166..85ab75f 100644
--- a/examples/Emojis/Program.cs
+++ b/examples/Emojis/Program.cs
@@ -1,4 +1,3 @@
-using System;
using Spectre.Console;
namespace Emojis
diff --git a/examples/Panel/Program.cs b/examples/Panel/Program.cs
index 3c4e112..3cd22b4 100644
--- a/examples/Panel/Program.cs
+++ b/examples/Panel/Program.cs
@@ -13,7 +13,7 @@ namespace PanelExample
AnsiConsole.Render(
new Panel(
new Panel(content)
- .SetBorder(Border.Rounded)));
+ .SetBorder(BoxBorder.Rounded)));
// Left adjusted panel with text
AnsiConsole.Render(
diff --git a/examples/Table/Program.cs b/examples/Table/Program.cs
index 27549ff..a16f0a9 100644
--- a/examples/Table/Program.cs
+++ b/examples/Table/Program.cs
@@ -35,7 +35,7 @@ namespace TableExample
private static void RenderBigTable()
{
// Create the table.
- var table = new Table().SetBorder(Border.Rounded);
+ var table = new Table().SetBorder(TableBorder.Rounded);
table.AddColumn("[red underline]Foo[/]");
table.AddColumn(new TableColumn("[blue]Bar[/]") { Alignment = Justify.Right, NoWrap = true });
@@ -57,7 +57,7 @@ namespace TableExample
private static void RenderNestedTable()
{
// Create simple table.
- var simple = new Table().SetBorder(Border.Rounded).SetBorderColor(Color.Red);
+ var simple = new Table().SetBorder(TableBorder.Rounded).SetBorderColor(Color.Red);
simple.AddColumn(new TableColumn("[u]Foo[/]").Centered());
simple.AddColumn(new TableColumn("[u]Bar[/]"));
simple.AddColumn(new TableColumn("[u]Baz[/]"));
@@ -66,7 +66,7 @@ namespace TableExample
simple.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
// Create other table.
- var second = new Table().SetBorder(Border.Square).SetBorderColor(Color.Green);
+ var second = new Table().SetBorder(TableBorder.Square).SetBorderColor(Color.Green);
second.AddColumn(new TableColumn("[u]Foo[/]"));
second.AddColumn(new TableColumn("[u]Bar[/]"));
second.AddColumn(new TableColumn("[u]Baz[/]"));
@@ -74,7 +74,7 @@ namespace TableExample
second.AddRow(simple, new Text("Whaaat"), new Text("Lolz"));
second.AddRow("[blue]Hej[/]", "[yellow]Världen![/]", "");
- var table = new Table().SetBorder(Border.Rounded);
+ var table = new Table().SetBorder(TableBorder.Rounded);
table.AddColumn(new TableColumn(new Panel("[u]Foo[/]").SetBorderColor(Color.Red)));
table.AddColumn(new TableColumn(new Panel("[u]Bar[/]").SetBorderColor(Color.Green)));
table.AddColumn(new TableColumn(new Panel("[u]Baz[/]").SetBorderColor(Color.Blue)));
diff --git a/global.json b/global.json
index 7c77738..54ed6bc 100644
--- a/global.json
+++ b/global.json
@@ -2,6 +2,6 @@
"projects": [ "src" ],
"sdk": {
"version": "3.1.301",
- "rollForward": "latestMajor"
+ "rollForward": "latestPatch"
}
}
\ No newline at end of file
diff --git a/src/Spectre.Console.Tests/Unit/BoxBorderTests.cs b/src/Spectre.Console.Tests/Unit/BoxBorderTests.cs
new file mode 100644
index 0000000..4c8c218
--- /dev/null
+++ b/src/Spectre.Console.Tests/Unit/BoxBorderTests.cs
@@ -0,0 +1,210 @@
+using Shouldly;
+using Spectre.Console.Rendering;
+using Xunit;
+
+namespace Spectre.Console.Tests.Unit
+{
+ public sealed class BoxBorderTests
+ {
+ public sealed class NoBorder
+ {
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = BoxBorder.None.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(BoxBorder.None);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var panel = Fixture.GetPanel().NoBorder();
+
+ // When
+ console.Render(panel);
+
+ // Then
+ console.Lines.Count.ShouldBe(3);
+ console.Lines[0].ShouldBe(" Greeting ");
+ console.Lines[1].ShouldBe(" Hello World ");
+ console.Lines[2].ShouldBe(" ");
+ }
+ }
+
+ public sealed class AsciiBorder
+ {
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = BoxBorder.Ascii.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(BoxBorder.Ascii);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var panel = Fixture.GetPanel().AsciiBorder();
+
+ // When
+ console.Render(panel);
+
+ // Then
+ console.Lines.Count.ShouldBe(3);
+ console.Lines[0].ShouldBe("+-Greeting----+");
+ console.Lines[1].ShouldBe("| Hello World |");
+ console.Lines[2].ShouldBe("+-------------+");
+ }
+ }
+
+ public sealed class DoubleBorder
+ {
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = BoxBorder.Double.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(BoxBorder.Double);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var panel = Fixture.GetPanel().DoubleBorder();
+
+ // When
+ console.Render(panel);
+
+ // Then
+ console.Lines.Count.ShouldBe(3);
+ console.Lines[0].ShouldBe("╔═Greeting════╗");
+ console.Lines[1].ShouldBe("║ Hello World ║");
+ console.Lines[2].ShouldBe("╚═════════════╝");
+ }
+ }
+
+ public sealed class HeavyBorder
+ {
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = BoxBorder.Heavy.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(BoxBorder.Square);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var panel = Fixture.GetPanel().HeavyBorder();
+
+ // When
+ console.Render(panel);
+
+ // Then
+ console.Lines.Count.ShouldBe(3);
+ console.Lines[0].ShouldBe("┏━Greeting━━━━┓");
+ console.Lines[1].ShouldBe("┃ Hello World ┃");
+ console.Lines[2].ShouldBe("┗━━━━━━━━━━━━━┛");
+ }
+ }
+
+ public sealed class RoundedBorder
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = BoxBorder.Rounded.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(BoxBorder.Square);
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var panel = Fixture.GetPanel().RoundedBorder();
+
+ // When
+ console.Render(panel);
+
+ // Then
+ console.Lines.Count.ShouldBe(3);
+ console.Lines[0].ShouldBe("╭─Greeting────╮");
+ console.Lines[1].ShouldBe("│ Hello World │");
+ console.Lines[2].ShouldBe("╰─────────────╯");
+ }
+ }
+
+ public sealed class SquareBorder
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = BoxBorder.Square.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(BoxBorder.Square);
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var panel = Fixture.GetPanel().SquareBorder();
+
+ // When
+ console.Render(panel);
+
+ // Then
+ console.Lines.Count.ShouldBe(3);
+ console.Lines[0].ShouldBe("┌─Greeting────┐");
+ console.Lines[1].ShouldBe("│ Hello World │");
+ console.Lines[2].ShouldBe("└─────────────┘");
+ }
+ }
+
+ private static class Fixture
+ {
+ public static Panel GetPanel()
+ {
+ return new Panel("Hello World")
+ .SetHeader("Greeting");
+ }
+ }
+ }
+}
diff --git a/src/Spectre.Console.Tests/Unit/BorderTests.cs b/src/Spectre.Console.Tests/Unit/TableBorderTests.cs
similarity index 75%
rename from src/Spectre.Console.Tests/Unit/BorderTests.cs
rename to src/Spectre.Console.Tests/Unit/TableBorderTests.cs
index fdcd369..72fe572 100644
--- a/src/Spectre.Console.Tests/Unit/BorderTests.cs
+++ b/src/Spectre.Console.Tests/Unit/TableBorderTests.cs
@@ -4,7 +4,7 @@ using Xunit;
namespace Spectre.Console.Tests.Unit
{
- public sealed class BorderTests
+ public sealed class TableBorderTests
{
public sealed class NoBorder
{
@@ -12,7 +12,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.None.Visible;
+ var visibility = TableBorder.None.Visible;
// Then
visibility.ShouldBeFalse();
@@ -24,10 +24,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.None.GetSafeBorder(safe: true);
+ var border = TableBorder.None.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.None);
+ border.ShouldBeSameAs(TableBorder.None);
}
}
@@ -55,7 +55,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Ascii.Visible;
+ var visibility = TableBorder.Ascii.Visible;
// Then
visibility.ShouldBeTrue();
@@ -67,10 +67,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Ascii.GetSafeBorder(safe: true);
+ var border = TableBorder.Ascii.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Ascii);
+ border.ShouldBeSameAs(TableBorder.Ascii);
}
}
@@ -101,7 +101,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Ascii2.Visible;
+ var visibility = TableBorder.Ascii2.Visible;
// Then
visibility.ShouldBeTrue();
@@ -113,10 +113,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Ascii2.GetSafeBorder(safe: true);
+ var border = TableBorder.Ascii2.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Ascii2);
+ border.ShouldBeSameAs(TableBorder.Ascii2);
}
}
@@ -147,7 +147,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.AsciiDoubleHead.Visible;
+ var visibility = TableBorder.AsciiDoubleHead.Visible;
// Then
visibility.ShouldBeTrue();
@@ -159,10 +159,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.AsciiDoubleHead.GetSafeBorder(safe: true);
+ var border = TableBorder.AsciiDoubleHead.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.AsciiDoubleHead);
+ border.ShouldBeSameAs(TableBorder.AsciiDoubleHead);
}
}
@@ -193,7 +193,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Square.Visible;
+ var visibility = TableBorder.Square.Visible;
// Then
visibility.ShouldBeTrue();
@@ -205,10 +205,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Square.GetSafeBorder(safe: true);
+ var border = TableBorder.Square.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Square);
+ border.ShouldBeSameAs(TableBorder.Square);
}
}
@@ -239,7 +239,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Rounded.Visible;
+ var visibility = TableBorder.Rounded.Visible;
// Then
visibility.ShouldBeTrue();
@@ -251,10 +251,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Rounded.GetSafeBorder(safe: true);
+ var border = TableBorder.Rounded.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Square);
+ border.ShouldBeSameAs(TableBorder.Square);
}
}
@@ -285,7 +285,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Minimal.Visible;
+ var visibility = TableBorder.Minimal.Visible;
// Then
visibility.ShouldBeTrue();
@@ -297,10 +297,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Minimal.GetSafeBorder(safe: true);
+ var border = TableBorder.Minimal.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Minimal);
+ border.ShouldBeSameAs(TableBorder.Minimal);
}
}
@@ -331,7 +331,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.MinimalHeavyHead.Visible;
+ var visibility = TableBorder.MinimalHeavyHead.Visible;
// Then
visibility.ShouldBeTrue();
@@ -343,10 +343,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.MinimalHeavyHead.GetSafeBorder(safe: true);
+ var border = TableBorder.MinimalHeavyHead.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Minimal);
+ border.ShouldBeSameAs(TableBorder.Minimal);
}
}
@@ -377,7 +377,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.MinimalDoubleHead.Visible;
+ var visibility = TableBorder.MinimalDoubleHead.Visible;
// Then
visibility.ShouldBeTrue();
@@ -389,10 +389,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.MinimalDoubleHead.GetSafeBorder(safe: true);
+ var border = TableBorder.MinimalDoubleHead.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.MinimalDoubleHead);
+ border.ShouldBeSameAs(TableBorder.MinimalDoubleHead);
}
}
@@ -423,7 +423,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Simple.Visible;
+ var visibility = TableBorder.Simple.Visible;
// Then
visibility.ShouldBeTrue();
@@ -435,10 +435,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Simple.GetSafeBorder(safe: true);
+ var border = TableBorder.Simple.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Simple);
+ border.ShouldBeSameAs(TableBorder.Simple);
}
}
@@ -469,7 +469,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Horizontal.Visible;
+ var visibility = TableBorder.Horizontal.Visible;
// Then
visibility.ShouldBeTrue();
@@ -481,10 +481,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Horizontal.GetSafeBorder(safe: true);
+ var border = TableBorder.Horizontal.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Horizontal);
+ border.ShouldBeSameAs(TableBorder.Horizontal);
}
}
@@ -515,7 +515,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.SimpleHeavy.Visible;
+ var visibility = TableBorder.SimpleHeavy.Visible;
// Then
visibility.ShouldBeTrue();
@@ -527,10 +527,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.SimpleHeavy.GetSafeBorder(safe: true);
+ var border = TableBorder.SimpleHeavy.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Simple);
+ border.ShouldBeSameAs(TableBorder.Simple);
}
}
@@ -561,7 +561,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Heavy.Visible;
+ var visibility = TableBorder.Heavy.Visible;
// Then
visibility.ShouldBeTrue();
@@ -573,10 +573,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Heavy.GetSafeBorder(safe: true);
+ var border = TableBorder.Heavy.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Square);
+ border.ShouldBeSameAs(TableBorder.Square);
}
}
@@ -607,7 +607,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.HeavyEdge.Visible;
+ var visibility = TableBorder.HeavyEdge.Visible;
// Then
visibility.ShouldBeTrue();
@@ -619,10 +619,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.HeavyEdge.GetSafeBorder(safe: true);
+ var border = TableBorder.HeavyEdge.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Square);
+ border.ShouldBeSameAs(TableBorder.Square);
}
}
@@ -653,7 +653,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.HeavyHead.Visible;
+ var visibility = TableBorder.HeavyHead.Visible;
// Then
visibility.ShouldBeTrue();
@@ -665,10 +665,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.HeavyHead.GetSafeBorder(safe: true);
+ var border = TableBorder.HeavyHead.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Square);
+ border.ShouldBeSameAs(TableBorder.Square);
}
}
@@ -699,7 +699,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.Double.Visible;
+ var visibility = TableBorder.Double.Visible;
// Then
visibility.ShouldBeTrue();
@@ -711,10 +711,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.Double.GetSafeBorder(safe: true);
+ var border = TableBorder.Double.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.Double);
+ border.ShouldBeSameAs(TableBorder.Double);
}
}
@@ -745,7 +745,7 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Correct_Visibility()
{
// Given, When
- var visibility = Border.DoubleEdge.Visible;
+ var visibility = TableBorder.DoubleEdge.Visible;
// Then
visibility.ShouldBeTrue();
@@ -757,10 +757,10 @@ namespace Spectre.Console.Tests.Unit
public void Should_Return_Safe_Border()
{
// Given, When
- var border = Border.DoubleEdge.GetSafeBorder(safe: true);
+ var border = TableBorder.DoubleEdge.GetSafeBorder(safe: true);
// Then
- border.ShouldBeSameAs(Border.DoubleEdge);
+ border.ShouldBeSameAs(TableBorder.DoubleEdge);
}
}
@@ -785,12 +785,119 @@ namespace Spectre.Console.Tests.Unit
}
}
+ public sealed class MarkdownBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = TableBorder.Markdown.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = TableBorder.Markdown.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(TableBorder.Markdown);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().MarkdownBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
+ console.Lines[2].ShouldBe("| -------- | -------- |");
+ console.Lines[3].ShouldBe("| Cell | Cell |");
+ console.Lines[4].ShouldBe("| Cell | Cell |");
+ console.Lines[5].ShouldBe(" ");
+ }
+
+ [Fact]
+ public void Should_Render_Left_Aligned_Table_Columns_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable(header2: Justify.Left).MarkdownBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
+ console.Lines[2].ShouldBe("| -------- | :------- |");
+ console.Lines[3].ShouldBe("| Cell | Cell |");
+ console.Lines[4].ShouldBe("| Cell | Cell |");
+ console.Lines[5].ShouldBe(" ");
+ }
+
+ [Fact]
+ public void Should_Render_Center_Aligned_Table_Columns_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable(header2: Justify.Center).MarkdownBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
+ console.Lines[2].ShouldBe("| -------- | :------: |");
+ console.Lines[3].ShouldBe("| Cell | Cell |");
+ console.Lines[4].ShouldBe("| Cell | Cell |");
+ console.Lines[5].ShouldBe(" ");
+ }
+
+ [Fact]
+ public void Should_Render_Right_Aligned_Table_Columns_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable(header2: Justify.Right).MarkdownBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
+ console.Lines[2].ShouldBe("| -------- | -------: |");
+ console.Lines[3].ShouldBe("| Cell | Cell |");
+ console.Lines[4].ShouldBe("| Cell | Cell |");
+ console.Lines[5].ShouldBe(" ");
+ }
+ }
+
private static class Fixture
{
- public static Table GetTable()
+ public static Table GetTable(Justify? header1 = null, Justify? header2 = null)
{
var table = new Table();
- table.AddColumns("Header 1", "Header 2");
+ table.AddColumn("Header 1", c => c.Alignment = header1);
+ table.AddColumn("Header 2", c => c.Alignment = header2);
table.AddRow("Cell", "Cell");
table.AddRow("Cell", "Cell");
return table;
diff --git a/src/Spectre.Console.Tests/Unit/TableTests.cs b/src/Spectre.Console.Tests/Unit/TableTests.cs
index d761ec4..fa3cca2 100644
--- a/src/Spectre.Console.Tests/Unit/TableTests.cs
+++ b/src/Spectre.Console.Tests/Unit/TableTests.cs
@@ -173,7 +173,7 @@ namespace Spectre.Console.Tests.Unit
{
// A simple table
var console = new PlainConsole(width: 80);
- var table = new Table() { Border = Border.Rounded };
+ var table = new Table() { Border = TableBorder.Rounded };
table.AddColumn("Foo");
table.AddColumn("Bar");
table.AddColumn(new TableColumn("Baz") { Alignment = Justify.Right });
@@ -183,7 +183,7 @@ namespace Spectre.Console.Tests.Unit
// Render a table in some panels.
console.Render(new Panel(new Panel(table)
{
- Border = Border.Ascii,
+ Border = BoxBorder.Ascii,
}));
// Then
@@ -255,7 +255,7 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var console = new PlainConsole(width: 80);
- var table = new Table { Border = Border.Ascii };
+ var table = new Table { Border = TableBorder.Ascii };
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
@@ -278,7 +278,7 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var console = new PlainConsole(width: 80);
- var table = new Table { Border = Border.Rounded };
+ var table = new Table { Border = TableBorder.Rounded };
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
@@ -301,7 +301,7 @@ namespace Spectre.Console.Tests.Unit
{
// Given
var console = new PlainConsole(width: 80);
- var table = new Table { Border = Border.None };
+ var table = new Table { Border = TableBorder.None };
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
diff --git a/src/Spectre.Console/Borders/Ascii2Border.cs b/src/Spectre.Console/Borders/Ascii2Border.cs
deleted file mode 100644
index 84e45a2..0000000
--- a/src/Spectre.Console/Borders/Ascii2Border.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents another old school ASCII border.
- ///
- public sealed class Ascii2Border : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "+",
- BorderPart.HeaderTop => "-",
- BorderPart.HeaderTopSeparator => "+",
- BorderPart.HeaderTopRight => "+",
- BorderPart.HeaderLeft => "|",
- BorderPart.HeaderSeparator => "|",
- BorderPart.HeaderRight => "|",
- BorderPart.HeaderBottomLeft => "|",
- BorderPart.HeaderBottom => "-",
- BorderPart.HeaderBottomSeparator => "+",
- BorderPart.HeaderBottomRight => "|",
- BorderPart.CellLeft => "|",
- BorderPart.CellSeparator => "|",
- BorderPart.CellRight => "|",
- BorderPart.FooterBottomLeft => "+",
- BorderPart.FooterBottom => "-",
- BorderPart.FooterBottomSeparator => "+",
- BorderPart.FooterBottomRight => "+",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/AsciiBorder.cs b/src/Spectre.Console/Borders/AsciiBorder.cs
deleted file mode 100644
index 0c8575f..0000000
--- a/src/Spectre.Console/Borders/AsciiBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents an old school ASCII border.
- ///
- public sealed class AsciiBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "+",
- BorderPart.HeaderTop => "-",
- BorderPart.HeaderTopSeparator => "-",
- BorderPart.HeaderTopRight => "+",
- BorderPart.HeaderLeft => "|",
- BorderPart.HeaderSeparator => "|",
- BorderPart.HeaderRight => "|",
- BorderPart.HeaderBottomLeft => "|",
- BorderPart.HeaderBottom => "-",
- BorderPart.HeaderBottomSeparator => "+",
- BorderPart.HeaderBottomRight => "|",
- BorderPart.CellLeft => "|",
- BorderPart.CellSeparator => "|",
- BorderPart.CellRight => "|",
- BorderPart.FooterBottomLeft => "+",
- BorderPart.FooterBottom => "-",
- BorderPart.FooterBottomSeparator => "-",
- BorderPart.FooterBottomRight => "+",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/AsciiDoubleHeadBorder.cs b/src/Spectre.Console/Borders/AsciiDoubleHeadBorder.cs
deleted file mode 100644
index 78116a5..0000000
--- a/src/Spectre.Console/Borders/AsciiDoubleHeadBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents an old school ASCII border with a double header border.
- ///
- public sealed class AsciiDoubleHeadBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "+",
- BorderPart.HeaderTop => "-",
- BorderPart.HeaderTopSeparator => "+",
- BorderPart.HeaderTopRight => "+",
- BorderPart.HeaderLeft => "|",
- BorderPart.HeaderSeparator => "|",
- BorderPart.HeaderRight => "|",
- BorderPart.HeaderBottomLeft => "|",
- BorderPart.HeaderBottom => "=",
- BorderPart.HeaderBottomSeparator => "+",
- BorderPart.HeaderBottomRight => "|",
- BorderPart.CellLeft => "|",
- BorderPart.CellSeparator => "|",
- BorderPart.CellRight => "|",
- BorderPart.FooterBottomLeft => "+",
- BorderPart.FooterBottom => "-",
- BorderPart.FooterBottomSeparator => "+",
- BorderPart.FooterBottomRight => "+",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/DoubleBorder.cs b/src/Spectre.Console/Borders/DoubleBorder.cs
deleted file mode 100644
index b0084c9..0000000
--- a/src/Spectre.Console/Borders/DoubleBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a double border.
- ///
- public sealed class DoubleBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "╔",
- BorderPart.HeaderTop => "═",
- BorderPart.HeaderTopSeparator => "╦",
- BorderPart.HeaderTopRight => "╗",
- BorderPart.HeaderLeft => "║",
- BorderPart.HeaderSeparator => "║",
- BorderPart.HeaderRight => "║",
- BorderPart.HeaderBottomLeft => "╠",
- BorderPart.HeaderBottom => "═",
- BorderPart.HeaderBottomSeparator => "╬",
- BorderPart.HeaderBottomRight => "╣",
- BorderPart.CellLeft => "║",
- BorderPart.CellSeparator => "║",
- BorderPart.CellRight => "║",
- BorderPart.FooterBottomLeft => "╚",
- BorderPart.FooterBottom => "═",
- BorderPart.FooterBottomSeparator => "╩",
- BorderPart.FooterBottomRight => "╝",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/DoubleEdgeBorder.cs b/src/Spectre.Console/Borders/DoubleEdgeBorder.cs
deleted file mode 100644
index b450681..0000000
--- a/src/Spectre.Console/Borders/DoubleEdgeBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a border with a double edge.
- ///
- public sealed class DoubleEdgeBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "╔",
- BorderPart.HeaderTop => "═",
- BorderPart.HeaderTopSeparator => "╤",
- BorderPart.HeaderTopRight => "╗",
- BorderPart.HeaderLeft => "║",
- BorderPart.HeaderSeparator => "│",
- BorderPart.HeaderRight => "║",
- BorderPart.HeaderBottomLeft => "╟",
- BorderPart.HeaderBottom => "─",
- BorderPart.HeaderBottomSeparator => "┼",
- BorderPart.HeaderBottomRight => "╢",
- BorderPart.CellLeft => "║",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => "║",
- BorderPart.FooterBottomLeft => "╚",
- BorderPart.FooterBottom => "═",
- BorderPart.FooterBottomSeparator => "╧",
- BorderPart.FooterBottomRight => "╝",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/HeavyBorder.cs b/src/Spectre.Console/Borders/HeavyBorder.cs
deleted file mode 100644
index 5a2f537..0000000
--- a/src/Spectre.Console/Borders/HeavyBorder.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a heavy border.
- ///
- public sealed class HeavyBorder : Border
- {
- ///
- public override Border? SafeBorder => Border.Square;
-
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "┏",
- BorderPart.HeaderTop => "━",
- BorderPart.HeaderTopSeparator => "┳",
- BorderPart.HeaderTopRight => "┓",
- BorderPart.HeaderLeft => "┃",
- BorderPart.HeaderSeparator => "┃",
- BorderPart.HeaderRight => "┃",
- BorderPart.HeaderBottomLeft => "┣",
- BorderPart.HeaderBottom => "━",
- BorderPart.HeaderBottomSeparator => "╋",
- BorderPart.HeaderBottomRight => "┫",
- BorderPart.CellLeft => "┃",
- BorderPart.CellSeparator => "┃",
- BorderPart.CellRight => "┃",
- BorderPart.FooterBottomLeft => "┗",
- BorderPart.FooterBottom => "━",
- BorderPart.FooterBottomSeparator => "┻",
- BorderPart.FooterBottomRight => "┛",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/HeavyEdgeBorder.cs b/src/Spectre.Console/Borders/HeavyEdgeBorder.cs
deleted file mode 100644
index c01b503..0000000
--- a/src/Spectre.Console/Borders/HeavyEdgeBorder.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a border with a heavy edge.
- ///
- public sealed class HeavyEdgeBorder : Border
- {
- ///
- public override Border? SafeBorder => Border.Square;
-
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "┏",
- BorderPart.HeaderTop => "━",
- BorderPart.HeaderTopSeparator => "┯",
- BorderPart.HeaderTopRight => "┓",
- BorderPart.HeaderLeft => "┃",
- BorderPart.HeaderSeparator => "│",
- BorderPart.HeaderRight => "┃",
- BorderPart.HeaderBottomLeft => "┠",
- BorderPart.HeaderBottom => "─",
- BorderPart.HeaderBottomSeparator => "┼",
- BorderPart.HeaderBottomRight => "┨",
- BorderPart.CellLeft => "┃",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => "┃",
- BorderPart.FooterBottomLeft => "┗",
- BorderPart.FooterBottom => "━",
- BorderPart.FooterBottomSeparator => "┷",
- BorderPart.FooterBottomRight => "┛",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/HeavyHeadBorder.cs b/src/Spectre.Console/Borders/HeavyHeadBorder.cs
deleted file mode 100644
index 7ba6538..0000000
--- a/src/Spectre.Console/Borders/HeavyHeadBorder.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a border with a heavy header.
- ///
- public sealed class HeavyHeadBorder : Border
- {
- ///
- public override Border? SafeBorder => Border.Square;
-
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "┏",
- BorderPart.HeaderTop => "━",
- BorderPart.HeaderTopSeparator => "┳",
- BorderPart.HeaderTopRight => "┓",
- BorderPart.HeaderLeft => "┃",
- BorderPart.HeaderSeparator => "┃",
- BorderPart.HeaderRight => "┃",
- BorderPart.HeaderBottomLeft => "┡",
- BorderPart.HeaderBottom => "━",
- BorderPart.HeaderBottomSeparator => "╇",
- BorderPart.HeaderBottomRight => "┩",
- BorderPart.CellLeft => "│",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => "│",
- BorderPart.FooterBottomLeft => "└",
- BorderPart.FooterBottom => "─",
- BorderPart.FooterBottomSeparator => "┴",
- BorderPart.FooterBottomRight => "┘",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/HorizontalBorder.cs b/src/Spectre.Console/Borders/HorizontalBorder.cs
deleted file mode 100644
index 4ba3209..0000000
--- a/src/Spectre.Console/Borders/HorizontalBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a horizontal border.
- ///
- public sealed class HorizontalBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "─",
- BorderPart.HeaderTop => "─",
- BorderPart.HeaderTopSeparator => "─",
- BorderPart.HeaderTopRight => "─",
- BorderPart.HeaderLeft => " ",
- BorderPart.HeaderSeparator => " ",
- BorderPart.HeaderRight => " ",
- BorderPart.HeaderBottomLeft => "─",
- BorderPart.HeaderBottom => "─",
- BorderPart.HeaderBottomSeparator => "─",
- BorderPart.HeaderBottomRight => "─",
- BorderPart.CellLeft => " ",
- BorderPart.CellSeparator => " ",
- BorderPart.CellRight => " ",
- BorderPart.FooterBottomLeft => "─",
- BorderPart.FooterBottom => "─",
- BorderPart.FooterBottomSeparator => "─",
- BorderPart.FooterBottomRight => "─",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/MinimalBorder.cs b/src/Spectre.Console/Borders/MinimalBorder.cs
deleted file mode 100644
index 056d28d..0000000
--- a/src/Spectre.Console/Borders/MinimalBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a minimal border.
- ///
- public sealed class MinimalBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => " ",
- BorderPart.HeaderTop => " ",
- BorderPart.HeaderTopSeparator => " ",
- BorderPart.HeaderTopRight => " ",
- BorderPart.HeaderLeft => " ",
- BorderPart.HeaderSeparator => "│",
- BorderPart.HeaderRight => " ",
- BorderPart.HeaderBottomLeft => " ",
- BorderPart.HeaderBottom => "─",
- BorderPart.HeaderBottomSeparator => "┼",
- BorderPart.HeaderBottomRight => " ",
- BorderPart.CellLeft => " ",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => " ",
- BorderPart.FooterBottomLeft => " ",
- BorderPart.FooterBottom => " ",
- BorderPart.FooterBottomSeparator => " ",
- BorderPart.FooterBottomRight => " ",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/MinimalDoubleHeadBorder.cs b/src/Spectre.Console/Borders/MinimalDoubleHeadBorder.cs
deleted file mode 100644
index 06c9353..0000000
--- a/src/Spectre.Console/Borders/MinimalDoubleHeadBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a minimal border with a double header border.
- ///
- public sealed class MinimalDoubleHeadBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => " ",
- BorderPart.HeaderTop => " ",
- BorderPart.HeaderTopSeparator => " ",
- BorderPart.HeaderTopRight => " ",
- BorderPart.HeaderLeft => " ",
- BorderPart.HeaderSeparator => "│",
- BorderPart.HeaderRight => " ",
- BorderPart.HeaderBottomLeft => " ",
- BorderPart.HeaderBottom => "═",
- BorderPart.HeaderBottomSeparator => "╪",
- BorderPart.HeaderBottomRight => " ",
- BorderPart.CellLeft => " ",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => " ",
- BorderPart.FooterBottomLeft => " ",
- BorderPart.FooterBottom => " ",
- BorderPart.FooterBottomSeparator => " ",
- BorderPart.FooterBottomRight => " ",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/MinimalHeavyHeadBorder.cs b/src/Spectre.Console/Borders/MinimalHeavyHeadBorder.cs
deleted file mode 100644
index 6233449..0000000
--- a/src/Spectre.Console/Borders/MinimalHeavyHeadBorder.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a minimal border with a heavy header.
- ///
- public sealed class MinimalHeavyHeadBorder : Border
- {
- ///
- public override Border? SafeBorder => Border.Minimal;
-
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => " ",
- BorderPart.HeaderTop => " ",
- BorderPart.HeaderTopSeparator => " ",
- BorderPart.HeaderTopRight => " ",
- BorderPart.HeaderLeft => " ",
- BorderPart.HeaderSeparator => "│",
- BorderPart.HeaderRight => " ",
- BorderPart.HeaderBottomLeft => " ",
- BorderPart.HeaderBottom => "━",
- BorderPart.HeaderBottomSeparator => "┿",
- BorderPart.HeaderBottomRight => " ",
- BorderPart.CellLeft => " ",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => " ",
- BorderPart.FooterBottomLeft => " ",
- BorderPart.FooterBottom => " ",
- BorderPart.FooterBottomSeparator => " ",
- BorderPart.FooterBottomRight => " ",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/RoundedBorder.cs b/src/Spectre.Console/Borders/RoundedBorder.cs
deleted file mode 100644
index 33aa634..0000000
--- a/src/Spectre.Console/Borders/RoundedBorder.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a rounded border.
- ///
- public sealed class RoundedBorder : Border
- {
- ///
- public override Border? SafeBorder { get; } = Border.Square;
-
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "╭",
- BorderPart.HeaderTop => "─",
- BorderPart.HeaderTopSeparator => "┬",
- BorderPart.HeaderTopRight => "╮",
- BorderPart.HeaderLeft => "│",
- BorderPart.HeaderSeparator => "│",
- BorderPart.HeaderRight => "│",
- BorderPart.HeaderBottomLeft => "├",
- BorderPart.HeaderBottom => "─",
- BorderPart.HeaderBottomSeparator => "┼",
- BorderPart.HeaderBottomRight => "┤",
- BorderPart.CellLeft => "│",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => "│",
- BorderPart.FooterBottomLeft => "╰",
- BorderPart.FooterBottom => "─",
- BorderPart.FooterBottomSeparator => "┴",
- BorderPart.FooterBottomRight => "╯",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/SimpleBorder.cs b/src/Spectre.Console/Borders/SimpleBorder.cs
deleted file mode 100644
index 481c6c4..0000000
--- a/src/Spectre.Console/Borders/SimpleBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a simple border.
- ///
- public sealed class SimpleBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => " ",
- BorderPart.HeaderTop => " ",
- BorderPart.HeaderTopSeparator => " ",
- BorderPart.HeaderTopRight => " ",
- BorderPart.HeaderLeft => " ",
- BorderPart.HeaderSeparator => " ",
- BorderPart.HeaderRight => " ",
- BorderPart.HeaderBottomLeft => "─",
- BorderPart.HeaderBottom => "─",
- BorderPart.HeaderBottomSeparator => "─",
- BorderPart.HeaderBottomRight => "─",
- BorderPart.CellLeft => " ",
- BorderPart.CellSeparator => " ",
- BorderPart.CellRight => " ",
- BorderPart.FooterBottomLeft => " ",
- BorderPart.FooterBottom => " ",
- BorderPart.FooterBottomSeparator => " ",
- BorderPart.FooterBottomRight => " ",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/SimpleHeavyBorder.cs b/src/Spectre.Console/Borders/SimpleHeavyBorder.cs
deleted file mode 100644
index 20d47d4..0000000
--- a/src/Spectre.Console/Borders/SimpleHeavyBorder.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a simple border with heavy lines.
- ///
- public sealed class SimpleHeavyBorder : Border
- {
- ///
- public override Border? SafeBorder => Border.Simple;
-
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => " ",
- BorderPart.HeaderTop => " ",
- BorderPart.HeaderTopSeparator => " ",
- BorderPart.HeaderTopRight => " ",
- BorderPart.HeaderLeft => " ",
- BorderPart.HeaderSeparator => " ",
- BorderPart.HeaderRight => " ",
- BorderPart.HeaderBottomLeft => "━",
- BorderPart.HeaderBottom => "━",
- BorderPart.HeaderBottomSeparator => "━",
- BorderPart.HeaderBottomRight => "━",
- BorderPart.CellLeft => " ",
- BorderPart.CellSeparator => " ",
- BorderPart.CellRight => " ",
- BorderPart.FooterBottomLeft => " ",
- BorderPart.FooterBottom => " ",
- BorderPart.FooterBottomSeparator => " ",
- BorderPart.FooterBottomRight => " ",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/Borders/SquareBorder.cs b/src/Spectre.Console/Borders/SquareBorder.cs
deleted file mode 100644
index 1ba058e..0000000
--- a/src/Spectre.Console/Borders/SquareBorder.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Spectre.Console.Rendering
-{
- ///
- /// Represents a square border.
- ///
- public sealed class SquareBorder : Border
- {
- ///
- protected override string GetBoxPart(BorderPart part)
- {
- return part switch
- {
- BorderPart.HeaderTopLeft => "┌",
- BorderPart.HeaderTop => "─",
- BorderPart.HeaderTopSeparator => "┬",
- BorderPart.HeaderTopRight => "┐",
- BorderPart.HeaderLeft => "│",
- BorderPart.HeaderSeparator => "│",
- BorderPart.HeaderRight => "│",
- BorderPart.HeaderBottomLeft => "├",
- BorderPart.HeaderBottom => "─",
- BorderPart.HeaderBottomSeparator => "┼",
- BorderPart.HeaderBottomRight => "┤",
- BorderPart.CellLeft => "│",
- BorderPart.CellSeparator => "│",
- BorderPart.CellRight => "│",
- BorderPart.FooterBottomLeft => "└",
- BorderPart.FooterBottom => "─",
- BorderPart.FooterBottomSeparator => "┴",
- BorderPart.FooterBottomRight => "┘",
- _ => throw new InvalidOperationException("Unknown box part."),
- };
- }
- }
-}
diff --git a/src/Spectre.Console/BoxBorder.Known.cs b/src/Spectre.Console/BoxBorder.Known.cs
new file mode 100644
index 0000000..192648c
--- /dev/null
+++ b/src/Spectre.Console/BoxBorder.Known.cs
@@ -0,0 +1,42 @@
+using System.Diagnostics.CodeAnalysis;
+using Spectre.Console.Rendering;
+
+namespace Spectre.Console
+{
+ ///
+ /// Represents a border.
+ ///
+ public abstract partial class BoxBorder
+ {
+ ///
+ /// Gets an invisible border.
+ ///
+ public static BoxBorder None { get; } = new NoBoxBorder();
+
+ ///
+ /// Gets an ASCII border.
+ ///
+ public static BoxBorder Ascii { get; } = new AsciiBoxBorder();
+
+ ///
+ /// Gets a double border.
+ ///
+ [SuppressMessage("Naming", "CA1720:Identifier contains type name")]
+ public static BoxBorder Double { get; } = new DoubleBoxBorder();
+
+ ///
+ /// Gets a heavy border.
+ ///
+ public static BoxBorder Heavy { get; } = new HeavyBoxBorder();
+
+ ///
+ /// Gets a rounded border.
+ ///
+ public static BoxBorder Rounded { get; } = new RoundedBoxBorder();
+
+ ///
+ /// Gets a square border.
+ ///
+ public static BoxBorder Square { get; } = new SquareBoxBorder();
+ }
+}
diff --git a/src/Spectre.Console/Border.cs b/src/Spectre.Console/BoxBorder.cs
similarity index 67%
rename from src/Spectre.Console/Border.cs
rename to src/Spectre.Console/BoxBorder.cs
index 45355ea..d40f75e 100644
--- a/src/Spectre.Console/Border.cs
+++ b/src/Spectre.Console/BoxBorder.cs
@@ -9,45 +9,40 @@ namespace Spectre.Console
///
/// Represents a border.
///
- public abstract partial class Border
+ public abstract partial class BoxBorder
{
- private readonly Dictionary _lookup;
-
- ///
- /// Gets a value indicating whether or not the border is visible.
- ///
- public virtual bool Visible { get; } = true;
+ private readonly Dictionary _lookup;
///
/// Gets the safe border for this border or null if none exist.
///
- public virtual Border? SafeBorder { get; }
+ public virtual BoxBorder? SafeBorder { get; }
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- protected Border()
+ protected BoxBorder()
{
_lookup = Initialize();
}
- private Dictionary Initialize()
+ private Dictionary Initialize()
{
- var lookup = new Dictionary();
- foreach (BorderPart? part in Enum.GetValues(typeof(BorderPart)))
+ var lookup = new Dictionary();
+ foreach (BoxBorderPart? part in Enum.GetValues(typeof(BoxBorderPart)))
{
if (part == null)
{
continue;
}
- var text = GetBoxPart(part.Value);
+ var text = GetBorderPart(part.Value);
if (text.Length > 1)
{
throw new InvalidOperationException("A box part cannot contain more than one character.");
}
- lookup.Add(part.Value, GetBoxPart(part.Value));
+ lookup.Add(part.Value, GetBorderPart(part.Value));
}
return lookup;
@@ -59,10 +54,10 @@ namespace Spectre.Console
/// The part to get a string representation for.
/// The number of repetitions.
/// A string representation of the specified border part.
- public string GetPart(BorderPart part, int count)
+ public string GetPart(BoxBorderPart part, int count)
{
// TODO: This need some optimization...
- return string.Join(string.Empty, Enumerable.Repeat(GetBoxPart(part)[0], count));
+ return string.Join(string.Empty, Enumerable.Repeat(GetBorderPart(part)[0], count));
}
///
@@ -70,7 +65,7 @@ namespace Spectre.Console
///
/// The part to get a string representation for.
/// A string representation of the specified border part.
- public string GetPart(BorderPart part)
+ public string GetPart(BoxBorderPart part)
{
return _lookup[part].ToString(CultureInfo.InvariantCulture);
}
@@ -80,6 +75,6 @@ namespace Spectre.Console
///
/// The part to get the character representation for.
/// A character representation of the specified border part.
- protected abstract string GetBoxPart(BorderPart part);
+ protected abstract string GetBorderPart(BoxBorderPart part);
}
}
diff --git a/src/Spectre.Console/Color.cs b/src/Spectre.Console/Color.cs
index 12a990a..b58da6c 100644
--- a/src/Spectre.Console/Color.cs
+++ b/src/Spectre.Console/Color.cs
@@ -1,7 +1,6 @@
using System;
using System.Diagnostics;
using System.Globalization;
-using System.Security.Cryptography;
using Spectre.Console.Internal;
namespace Spectre.Console
diff --git a/src/Spectre.Console/Extensions/BorderExtensions.cs b/src/Spectre.Console/Extensions/BorderExtensions.cs
index 6357044..b32374c 100644
--- a/src/Spectre.Console/Extensions/BorderExtensions.cs
+++ b/src/Spectre.Console/Extensions/BorderExtensions.cs
@@ -3,7 +3,7 @@ using System;
namespace Spectre.Console.Rendering
{
///
- /// Contains extension methods for .
+ /// Contains extension methods for .
///
public static class BorderExtensions
{
@@ -13,7 +13,7 @@ namespace Spectre.Console.Rendering
/// The border to get the safe border for.
/// Whether or not to return the safe border.
/// The safe border if one exist, otherwise the original border.
- public static Border GetSafeBorder(this Border border, bool safe)
+ public static TableBorder GetSafeBorder(this TableBorder border, bool safe)
{
if (border is null)
{
diff --git a/src/Spectre.Console/Extensions/BoxExtensions.cs b/src/Spectre.Console/Extensions/BoxExtensions.cs
new file mode 100644
index 0000000..9dd5501
--- /dev/null
+++ b/src/Spectre.Console/Extensions/BoxExtensions.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Contains extension methods for .
+ ///
+ public static class BoxExtensions
+ {
+ ///
+ /// Gets the safe border for a border.
+ ///
+ /// The border to get the safe border for.
+ /// Whether or not to return the safe border.
+ /// The safe border if one exist, otherwise the original border.
+ public static BoxBorder GetSafeBorder(this BoxBorder border, bool safe)
+ {
+ if (border is null)
+ {
+ throw new ArgumentNullException(nameof(border));
+ }
+
+ if (safe && border.SafeBorder != null)
+ {
+ border = border.SafeBorder;
+ }
+
+ return border;
+ }
+ }
+}
diff --git a/src/Spectre.Console/Extensions/HasBorderExtensions.cs b/src/Spectre.Console/Extensions/HasBorderExtensions.cs
index a417176..107b8d0 100644
--- a/src/Spectre.Console/Extensions/HasBorderExtensions.cs
+++ b/src/Spectre.Console/Extensions/HasBorderExtensions.cs
@@ -7,229 +7,6 @@ namespace Spectre.Console
///
public static class HasBorderExtensions
{
- ///
- /// Do not display a border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T NoBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.None);
- }
-
- ///
- /// Display a square border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T SquareBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Square);
- }
-
- ///
- /// Display an ASCII border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T AsciiBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Ascii);
- }
-
- ///
- /// Display another ASCII border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T Ascii2Border(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Ascii2);
- }
-
- ///
- /// Display an ASCII border with a double header border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T AsciiDoubleHeadBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.AsciiDoubleHead);
- }
-
- ///
- /// Display a rounded border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T RoundedBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Rounded);
- }
-
- ///
- /// Display a minimal border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T MinimalBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Minimal);
- }
-
- ///
- /// Display a minimal border with a heavy head.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T MinimalHeavyHeadBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.MinimalHeavyHead);
- }
-
- ///
- /// Display a minimal border with a double header border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T MinimalDoubleHeadBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.MinimalDoubleHead);
- }
-
- ///
- /// Display a simple border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T SimpleBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Simple);
- }
-
- ///
- /// Display a simple border with heavy lines.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T SimpleHeavyBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.SimpleHeavy);
- }
-
- ///
- /// Display a simple border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T HorizontalBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Horizontal);
- }
-
- ///
- /// Display a heavy border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T HeavyBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Heavy);
- }
-
- ///
- /// Display a border with a heavy edge.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T HeavyEdgeBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.HeavyEdge);
- }
-
- ///
- /// Display a border with a heavy header.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T HeavyHeadBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.HeavyHead);
- }
-
- ///
- /// Display a double border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T DoubleBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.Double);
- }
-
- ///
- /// Display a border with a double edge.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The same instance so that multiple calls can be chained.
- public static T DoubleEdgeBorder(this T obj)
- where T : class, IHasBorder
- {
- return SetBorder(obj, Border.DoubleEdge);
- }
-
- ///
- /// Sets the border.
- ///
- /// An object type with a border.
- /// The object to set the border for.
- /// The border to use.
- /// The same instance so that multiple calls can be chained.
- public static T SetBorder(this T obj, Border border)
- where T : class, IHasBorder
- {
- if (obj is null)
- {
- throw new ArgumentNullException(nameof(obj));
- }
-
- obj.Border = border;
- return obj;
- }
-
///
/// Disables the safe border.
///
diff --git a/src/Spectre.Console/Extensions/HasBoxBorderExtensions.cs b/src/Spectre.Console/Extensions/HasBoxBorderExtensions.cs
new file mode 100644
index 0000000..a183b41
--- /dev/null
+++ b/src/Spectre.Console/Extensions/HasBoxBorderExtensions.cs
@@ -0,0 +1,101 @@
+using System;
+
+namespace Spectre.Console
+{
+ ///
+ /// Contains extension methods for .
+ ///
+ public static class HasBoxBorderExtensions
+ {
+ ///
+ /// Do not display a border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T NoBorder(this T obj)
+ where T : class, IHasBoxBorder
+ {
+ return SetBorder(obj, BoxBorder.None);
+ }
+
+ ///
+ /// Display a square border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T SquareBorder(this T obj)
+ where T : class, IHasBoxBorder
+ {
+ return SetBorder(obj, BoxBorder.Square);
+ }
+
+ ///
+ /// Display an ASCII border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T AsciiBorder(this T obj)
+ where T : class, IHasBoxBorder
+ {
+ return SetBorder(obj, BoxBorder.Ascii);
+ }
+
+ ///
+ /// Display a rounded border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T RoundedBorder(this T obj)
+ where T : class, IHasBoxBorder
+ {
+ return SetBorder(obj, BoxBorder.Rounded);
+ }
+
+ ///
+ /// Display a heavy border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HeavyBorder(this T obj)
+ where T : class, IHasBoxBorder
+ {
+ return SetBorder(obj, BoxBorder.Heavy);
+ }
+
+ ///
+ /// Display a double border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T DoubleBorder(this T obj)
+ where T : class, IHasBoxBorder
+ {
+ return SetBorder(obj, BoxBorder.Double);
+ }
+
+ ///
+ /// Sets the border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The border to use.
+ /// The same instance so that multiple calls can be chained.
+ public static T SetBorder(this T obj, BoxBorder border)
+ where T : class, IHasBoxBorder
+ {
+ if (obj is null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+
+ obj.Border = border;
+ return obj;
+ }
+ }
+}
diff --git a/src/Spectre.Console/Extensions/HasTableBorderExtensions.cs b/src/Spectre.Console/Extensions/HasTableBorderExtensions.cs
new file mode 100644
index 0000000..9cba8b1
--- /dev/null
+++ b/src/Spectre.Console/Extensions/HasTableBorderExtensions.cs
@@ -0,0 +1,245 @@
+using System;
+
+namespace Spectre.Console
+{
+ ///
+ /// Contains extension methods for .
+ ///
+ public static class HasTableBorderExtensions
+ {
+ ///
+ /// Do not display a border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T NoBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.None);
+ }
+
+ ///
+ /// Display a square border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T SquareBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Square);
+ }
+
+ ///
+ /// Display an ASCII border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T AsciiBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Ascii);
+ }
+
+ ///
+ /// Display another ASCII border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T Ascii2Border(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Ascii2);
+ }
+
+ ///
+ /// Display an ASCII border with a double header border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T AsciiDoubleHeadBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.AsciiDoubleHead);
+ }
+
+ ///
+ /// Display a rounded border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T RoundedBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Rounded);
+ }
+
+ ///
+ /// Display a minimal border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T MinimalBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Minimal);
+ }
+
+ ///
+ /// Display a minimal border with a heavy head.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T MinimalHeavyHeadBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.MinimalHeavyHead);
+ }
+
+ ///
+ /// Display a minimal border with a double header border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T MinimalDoubleHeadBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.MinimalDoubleHead);
+ }
+
+ ///
+ /// Display a simple border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T SimpleBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Simple);
+ }
+
+ ///
+ /// Display a simple border with heavy lines.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T SimpleHeavyBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.SimpleHeavy);
+ }
+
+ ///
+ /// Display a simple border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HorizontalBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Horizontal);
+ }
+
+ ///
+ /// Display a heavy border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HeavyBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Heavy);
+ }
+
+ ///
+ /// Display a border with a heavy edge.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HeavyEdgeBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.HeavyEdge);
+ }
+
+ ///
+ /// Display a border with a heavy header.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HeavyHeadBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.HeavyHead);
+ }
+
+ ///
+ /// Display a double border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T DoubleBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Double);
+ }
+
+ ///
+ /// Display a border with a double edge.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T DoubleEdgeBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.DoubleEdge);
+ }
+
+ ///
+ /// Display a markdown border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T MarkdownBorder(this T obj)
+ where T : class, IHasTableBorder
+ {
+ return SetBorder(obj, TableBorder.Markdown);
+ }
+
+ ///
+ /// Sets the border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The border to use.
+ /// The same instance so that multiple calls can be chained.
+ public static T SetBorder(this T obj, TableBorder border)
+ where T : class, IHasTableBorder
+ {
+ if (obj is null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+
+ obj.Border = border;
+ return obj;
+ }
+ }
+}
diff --git a/src/Spectre.Console/IHasBorder.cs b/src/Spectre.Console/IHasBorder.cs
index cde0c95..9a4f0de 100644
--- a/src/Spectre.Console/IHasBorder.cs
+++ b/src/Spectre.Console/IHasBorder.cs
@@ -13,12 +13,7 @@ namespace Spectre.Console
bool UseSafeBorder { get; set; }
///
- /// Gets or sets the border.
- ///
- public Border Border { get; set; }
-
- ///
- /// Gets or sets the border style.
+ /// Gets or sets the box style.
///
public Style? BorderStyle { get; set; }
}
diff --git a/src/Spectre.Console/IHasBoxBorder.cs b/src/Spectre.Console/IHasBoxBorder.cs
new file mode 100644
index 0000000..bb5f97b
--- /dev/null
+++ b/src/Spectre.Console/IHasBoxBorder.cs
@@ -0,0 +1,13 @@
+namespace Spectre.Console
+{
+ ///
+ /// Represents something that has a box border.
+ ///
+ public interface IHasBoxBorder : IHasBorder
+ {
+ ///
+ /// Gets or sets the box.
+ ///
+ public BoxBorder Border { get; set; }
+ }
+}
diff --git a/src/Spectre.Console/IHasTableBorder.cs b/src/Spectre.Console/IHasTableBorder.cs
new file mode 100644
index 0000000..0cbe19f
--- /dev/null
+++ b/src/Spectre.Console/IHasTableBorder.cs
@@ -0,0 +1,13 @@
+namespace Spectre.Console
+{
+ ///
+ /// Represents something that has a border.
+ ///
+ public interface IHasTableBorder : IHasBorder
+ {
+ ///
+ /// Gets or sets the border.
+ ///
+ public TableBorder Border { get; set; }
+ }
+}
diff --git a/src/Spectre.Console/Internal/Extensions/StringExtensions.cs b/src/Spectre.Console/Internal/Extensions/StringExtensions.cs
index 1c79d0a..00e91d4 100644
--- a/src/Spectre.Console/Internal/Extensions/StringExtensions.cs
+++ b/src/Spectre.Console/Internal/Extensions/StringExtensions.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
using Spectre.Console.Rendering;
@@ -80,27 +81,24 @@ namespace Spectre.Console.Internal
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)
+ public static string Multiply(this string text, int count)
{
- unchecked
+ if (text is null)
{
- 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);
+ throw new ArgumentNullException(nameof(text));
}
+
+ if (count <= 0)
+ {
+ return string.Empty;
+ }
+
+ if (count == 1)
+ {
+ return text;
+ }
+
+ return string.Concat(Enumerable.Repeat(text, count));
}
}
}
diff --git a/src/Spectre.Console/Rendering/Borders/BoxBorderPart.cs b/src/Spectre.Console/Rendering/Borders/BoxBorderPart.cs
new file mode 100644
index 0000000..10f79a5
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/BoxBorderPart.cs
@@ -0,0 +1,48 @@
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents the different parts of a box border.
+ ///
+ public enum BoxBorderPart
+ {
+ ///
+ /// The top left part of a box.
+ ///
+ TopLeft,
+
+ ///
+ /// The top part of a box.
+ ///
+ Top,
+
+ ///
+ /// The top right part of a box.
+ ///
+ TopRight,
+
+ ///
+ /// The left part of a box.
+ ///
+ Left,
+
+ ///
+ /// The right part of a box.
+ ///
+ Right,
+
+ ///
+ /// The bottom left part of a box.
+ ///
+ BottomLeft,
+
+ ///
+ /// The bottom part of a box.
+ ///
+ Bottom,
+
+ ///
+ /// The bottom right part of a box.
+ ///
+ BottomRight,
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Boxes/AsciiBoxBorder.cs b/src/Spectre.Console/Rendering/Borders/Boxes/AsciiBoxBorder.cs
new file mode 100644
index 0000000..4d883e9
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Boxes/AsciiBoxBorder.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents an old school ASCII border.
+ ///
+ public sealed class AsciiBoxBorder : BoxBorder
+ {
+ ///
+ protected override string GetBorderPart(BoxBorderPart part)
+ {
+ return part switch
+ {
+ BoxBorderPart.TopLeft => "+",
+ BoxBorderPart.Top => "-",
+ BoxBorderPart.TopRight => "+",
+ BoxBorderPart.Left => "|",
+ BoxBorderPart.Right => "|",
+ BoxBorderPart.BottomLeft => "+",
+ BoxBorderPart.Bottom => "-",
+ BoxBorderPart.BottomRight => "+",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Boxes/DoubleBoxBorder.cs b/src/Spectre.Console/Rendering/Borders/Boxes/DoubleBoxBorder.cs
new file mode 100644
index 0000000..010ff4c
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Boxes/DoubleBoxBorder.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a double border.
+ ///
+ public sealed class DoubleBoxBorder : BoxBorder
+ {
+ ///
+ protected override string GetBorderPart(BoxBorderPart part)
+ {
+ return part switch
+ {
+ BoxBorderPart.TopLeft => "╔",
+ BoxBorderPart.Top => "═",
+ BoxBorderPart.TopRight => "╗",
+ BoxBorderPart.Left => "║",
+ BoxBorderPart.Right => "║",
+ BoxBorderPart.BottomLeft => "╚",
+ BoxBorderPart.Bottom => "═",
+ BoxBorderPart.BottomRight => "╝",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Boxes/HeavyBoxBorder.cs b/src/Spectre.Console/Rendering/Borders/Boxes/HeavyBoxBorder.cs
new file mode 100644
index 0000000..3b13f67
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Boxes/HeavyBoxBorder.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a heavy border.
+ ///
+ public sealed class HeavyBoxBorder : BoxBorder
+ {
+ ///
+ public override BoxBorder? SafeBorder => BoxBorder.Square;
+
+ ///
+ protected override string GetBorderPart(BoxBorderPart part)
+ {
+ return part switch
+ {
+ BoxBorderPart.TopLeft => "┏",
+ BoxBorderPart.Top => "━",
+ BoxBorderPart.TopRight => "┓",
+ BoxBorderPart.Left => "┃",
+ BoxBorderPart.Right => "┃",
+ BoxBorderPart.BottomLeft => "┗",
+ BoxBorderPart.Bottom => "━",
+ BoxBorderPart.BottomRight => "┛",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Boxes/NoBoxBorder.cs b/src/Spectre.Console/Rendering/Borders/Boxes/NoBoxBorder.cs
new file mode 100644
index 0000000..504e754
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Boxes/NoBoxBorder.cs
@@ -0,0 +1,14 @@
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents an invisible border.
+ ///
+ public sealed class NoBoxBorder : BoxBorder
+ {
+ ///
+ protected override string GetBorderPart(BoxBorderPart part)
+ {
+ return " ";
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Boxes/RoundedBoxBorder.cs b/src/Spectre.Console/Rendering/Borders/Boxes/RoundedBoxBorder.cs
new file mode 100644
index 0000000..c4ffaeb
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Boxes/RoundedBoxBorder.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a rounded border.
+ ///
+ public sealed class RoundedBoxBorder : BoxBorder
+ {
+ ///
+ public override BoxBorder? SafeBorder => BoxBorder.Square;
+
+ ///
+ protected override string GetBorderPart(BoxBorderPart part)
+ {
+ return part switch
+ {
+ BoxBorderPart.TopLeft => "╭",
+ BoxBorderPart.Top => "─",
+ BoxBorderPart.TopRight => "╮",
+ BoxBorderPart.Left => "│",
+ BoxBorderPart.Right => "│",
+ BoxBorderPart.BottomLeft => "╰",
+ BoxBorderPart.Bottom => "─",
+ BoxBorderPart.BottomRight => "╯",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Boxes/SquareBoxBorder.cs b/src/Spectre.Console/Rendering/Borders/Boxes/SquareBoxBorder.cs
new file mode 100644
index 0000000..2374b93
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Boxes/SquareBoxBorder.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a square border.
+ ///
+ public sealed class SquareBoxBorder : BoxBorder
+ {
+ ///
+ protected override string GetBorderPart(BoxBorderPart part)
+ {
+ return part switch
+ {
+ BoxBorderPart.TopLeft => "┌",
+ BoxBorderPart.Top => "─",
+ BoxBorderPart.TopRight => "┐",
+ BoxBorderPart.Left => "│",
+ BoxBorderPart.Right => "│",
+ BoxBorderPart.BottomLeft => "└",
+ BoxBorderPart.Bottom => "─",
+ BoxBorderPart.BottomRight => "┘",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/BorderPart.cs b/src/Spectre.Console/Rendering/Borders/TableBorderPart.cs
similarity index 95%
rename from src/Spectre.Console/Rendering/BorderPart.cs
rename to src/Spectre.Console/Rendering/Borders/TableBorderPart.cs
index 0f23ca3..370ad20 100644
--- a/src/Spectre.Console/Rendering/BorderPart.cs
+++ b/src/Spectre.Console/Rendering/Borders/TableBorderPart.cs
@@ -1,9 +1,9 @@
namespace Spectre.Console.Rendering
{
///
- /// Represents the different border parts.
+ /// Represents the different parts of a table border.
///
- public enum BorderPart
+ public enum TableBorderPart
{
///
/// The top left part of a header.
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/Ascii2TableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/Ascii2TableBorder.cs
new file mode 100644
index 0000000..b3f2cd7
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/Ascii2TableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents another old school ASCII border.
+ ///
+ public sealed class Ascii2TableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "+",
+ TableBorderPart.HeaderTop => "-",
+ TableBorderPart.HeaderTopSeparator => "+",
+ TableBorderPart.HeaderTopRight => "+",
+ TableBorderPart.HeaderLeft => "|",
+ TableBorderPart.HeaderSeparator => "|",
+ TableBorderPart.HeaderRight => "|",
+ TableBorderPart.HeaderBottomLeft => "|",
+ TableBorderPart.HeaderBottom => "-",
+ TableBorderPart.HeaderBottomSeparator => "+",
+ TableBorderPart.HeaderBottomRight => "|",
+ TableBorderPart.CellLeft => "|",
+ TableBorderPart.CellSeparator => "|",
+ TableBorderPart.CellRight => "|",
+ TableBorderPart.FooterBottomLeft => "+",
+ TableBorderPart.FooterBottom => "-",
+ TableBorderPart.FooterBottomSeparator => "+",
+ TableBorderPart.FooterBottomRight => "+",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/AsciiDoubleHeadTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/AsciiDoubleHeadTableBorder.cs
new file mode 100644
index 0000000..1e36b14
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/AsciiDoubleHeadTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents an old school ASCII border with a double header border.
+ ///
+ public sealed class AsciiDoubleHeadTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "+",
+ TableBorderPart.HeaderTop => "-",
+ TableBorderPart.HeaderTopSeparator => "+",
+ TableBorderPart.HeaderTopRight => "+",
+ TableBorderPart.HeaderLeft => "|",
+ TableBorderPart.HeaderSeparator => "|",
+ TableBorderPart.HeaderRight => "|",
+ TableBorderPart.HeaderBottomLeft => "|",
+ TableBorderPart.HeaderBottom => "=",
+ TableBorderPart.HeaderBottomSeparator => "+",
+ TableBorderPart.HeaderBottomRight => "|",
+ TableBorderPart.CellLeft => "|",
+ TableBorderPart.CellSeparator => "|",
+ TableBorderPart.CellRight => "|",
+ TableBorderPart.FooterBottomLeft => "+",
+ TableBorderPart.FooterBottom => "-",
+ TableBorderPart.FooterBottomSeparator => "+",
+ TableBorderPart.FooterBottomRight => "+",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/AsciiTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/AsciiTableBorder.cs
new file mode 100644
index 0000000..cc1ea2d
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/AsciiTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents an old school ASCII border.
+ ///
+ public sealed class AsciiTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "+",
+ TableBorderPart.HeaderTop => "-",
+ TableBorderPart.HeaderTopSeparator => "-",
+ TableBorderPart.HeaderTopRight => "+",
+ TableBorderPart.HeaderLeft => "|",
+ TableBorderPart.HeaderSeparator => "|",
+ TableBorderPart.HeaderRight => "|",
+ TableBorderPart.HeaderBottomLeft => "|",
+ TableBorderPart.HeaderBottom => "-",
+ TableBorderPart.HeaderBottomSeparator => "+",
+ TableBorderPart.HeaderBottomRight => "|",
+ TableBorderPart.CellLeft => "|",
+ TableBorderPart.CellSeparator => "|",
+ TableBorderPart.CellRight => "|",
+ TableBorderPart.FooterBottomLeft => "+",
+ TableBorderPart.FooterBottom => "-",
+ TableBorderPart.FooterBottomSeparator => "-",
+ TableBorderPart.FooterBottomRight => "+",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/DoubleEdgeTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/DoubleEdgeTableBorder.cs
new file mode 100644
index 0000000..fe0e8d7
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/DoubleEdgeTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a border with a double edge.
+ ///
+ public sealed class DoubleEdgeTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "╔",
+ TableBorderPart.HeaderTop => "═",
+ TableBorderPart.HeaderTopSeparator => "╤",
+ TableBorderPart.HeaderTopRight => "╗",
+ TableBorderPart.HeaderLeft => "║",
+ TableBorderPart.HeaderSeparator => "│",
+ TableBorderPart.HeaderRight => "║",
+ TableBorderPart.HeaderBottomLeft => "╟",
+ TableBorderPart.HeaderBottom => "─",
+ TableBorderPart.HeaderBottomSeparator => "┼",
+ TableBorderPart.HeaderBottomRight => "╢",
+ TableBorderPart.CellLeft => "║",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => "║",
+ TableBorderPart.FooterBottomLeft => "╚",
+ TableBorderPart.FooterBottom => "═",
+ TableBorderPart.FooterBottomSeparator => "╧",
+ TableBorderPart.FooterBottomRight => "╝",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/DoubleTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/DoubleTableBorder.cs
new file mode 100644
index 0000000..7fdf06b
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/DoubleTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a double border.
+ ///
+ public sealed class DoubleTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "╔",
+ TableBorderPart.HeaderTop => "═",
+ TableBorderPart.HeaderTopSeparator => "╦",
+ TableBorderPart.HeaderTopRight => "╗",
+ TableBorderPart.HeaderLeft => "║",
+ TableBorderPart.HeaderSeparator => "║",
+ TableBorderPart.HeaderRight => "║",
+ TableBorderPart.HeaderBottomLeft => "╠",
+ TableBorderPart.HeaderBottom => "═",
+ TableBorderPart.HeaderBottomSeparator => "╬",
+ TableBorderPart.HeaderBottomRight => "╣",
+ TableBorderPart.CellLeft => "║",
+ TableBorderPart.CellSeparator => "║",
+ TableBorderPart.CellRight => "║",
+ TableBorderPart.FooterBottomLeft => "╚",
+ TableBorderPart.FooterBottom => "═",
+ TableBorderPart.FooterBottomSeparator => "╩",
+ TableBorderPart.FooterBottomRight => "╝",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/HeavyEdgeTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/HeavyEdgeTableBorder.cs
new file mode 100644
index 0000000..9aa3c92
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/HeavyEdgeTableBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a border with a heavy edge.
+ ///
+ public sealed class HeavyEdgeTableBorder : TableBorder
+ {
+ ///
+ public override TableBorder? SafeBorder => TableBorder.Square;
+
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "┏",
+ TableBorderPart.HeaderTop => "━",
+ TableBorderPart.HeaderTopSeparator => "┯",
+ TableBorderPart.HeaderTopRight => "┓",
+ TableBorderPart.HeaderLeft => "┃",
+ TableBorderPart.HeaderSeparator => "│",
+ TableBorderPart.HeaderRight => "┃",
+ TableBorderPart.HeaderBottomLeft => "┠",
+ TableBorderPart.HeaderBottom => "─",
+ TableBorderPart.HeaderBottomSeparator => "┼",
+ TableBorderPart.HeaderBottomRight => "┨",
+ TableBorderPart.CellLeft => "┃",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => "┃",
+ TableBorderPart.FooterBottomLeft => "┗",
+ TableBorderPart.FooterBottom => "━",
+ TableBorderPart.FooterBottomSeparator => "┷",
+ TableBorderPart.FooterBottomRight => "┛",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/HeavyHeadTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/HeavyHeadTableBorder.cs
new file mode 100644
index 0000000..d51401f
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/HeavyHeadTableBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a border with a heavy header.
+ ///
+ public sealed class HeavyHeadTableBorder : TableBorder
+ {
+ ///
+ public override TableBorder? SafeBorder => TableBorder.Square;
+
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "┏",
+ TableBorderPart.HeaderTop => "━",
+ TableBorderPart.HeaderTopSeparator => "┳",
+ TableBorderPart.HeaderTopRight => "┓",
+ TableBorderPart.HeaderLeft => "┃",
+ TableBorderPart.HeaderSeparator => "┃",
+ TableBorderPart.HeaderRight => "┃",
+ TableBorderPart.HeaderBottomLeft => "┡",
+ TableBorderPart.HeaderBottom => "━",
+ TableBorderPart.HeaderBottomSeparator => "╇",
+ TableBorderPart.HeaderBottomRight => "┩",
+ TableBorderPart.CellLeft => "│",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => "│",
+ TableBorderPart.FooterBottomLeft => "└",
+ TableBorderPart.FooterBottom => "─",
+ TableBorderPart.FooterBottomSeparator => "┴",
+ TableBorderPart.FooterBottomRight => "┘",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/HeavyTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/HeavyTableBorder.cs
new file mode 100644
index 0000000..e7c6d90
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/HeavyTableBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a heavy border.
+ ///
+ public sealed class HeavyTableBorder : TableBorder
+ {
+ ///
+ public override TableBorder? SafeBorder => TableBorder.Square;
+
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "┏",
+ TableBorderPart.HeaderTop => "━",
+ TableBorderPart.HeaderTopSeparator => "┳",
+ TableBorderPart.HeaderTopRight => "┓",
+ TableBorderPart.HeaderLeft => "┃",
+ TableBorderPart.HeaderSeparator => "┃",
+ TableBorderPart.HeaderRight => "┃",
+ TableBorderPart.HeaderBottomLeft => "┣",
+ TableBorderPart.HeaderBottom => "━",
+ TableBorderPart.HeaderBottomSeparator => "╋",
+ TableBorderPart.HeaderBottomRight => "┫",
+ TableBorderPart.CellLeft => "┃",
+ TableBorderPart.CellSeparator => "┃",
+ TableBorderPart.CellRight => "┃",
+ TableBorderPart.FooterBottomLeft => "┗",
+ TableBorderPart.FooterBottom => "━",
+ TableBorderPart.FooterBottomSeparator => "┻",
+ TableBorderPart.FooterBottomRight => "┛",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/HorizontalTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/HorizontalTableBorder.cs
new file mode 100644
index 0000000..e8cb667
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/HorizontalTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a horizontal border.
+ ///
+ public sealed class HorizontalTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "─",
+ TableBorderPart.HeaderTop => "─",
+ TableBorderPart.HeaderTopSeparator => "─",
+ TableBorderPart.HeaderTopRight => "─",
+ TableBorderPart.HeaderLeft => " ",
+ TableBorderPart.HeaderSeparator => " ",
+ TableBorderPart.HeaderRight => " ",
+ TableBorderPart.HeaderBottomLeft => "─",
+ TableBorderPart.HeaderBottom => "─",
+ TableBorderPart.HeaderBottomSeparator => "─",
+ TableBorderPart.HeaderBottomRight => "─",
+ TableBorderPart.CellLeft => " ",
+ TableBorderPart.CellSeparator => " ",
+ TableBorderPart.CellRight => " ",
+ TableBorderPart.FooterBottomLeft => "─",
+ TableBorderPart.FooterBottom => "─",
+ TableBorderPart.FooterBottomSeparator => "─",
+ TableBorderPart.FooterBottomRight => "─",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/MarkdownTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/MarkdownTableBorder.cs
new file mode 100644
index 0000000..4e734f2
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/MarkdownTableBorder.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Spectre.Console.Internal;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a Markdown border.
+ ///
+ public sealed class MarkdownTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => " ",
+ TableBorderPart.HeaderTop => " ",
+ TableBorderPart.HeaderTopSeparator => " ",
+ TableBorderPart.HeaderTopRight => " ",
+ TableBorderPart.HeaderLeft => "|",
+ TableBorderPart.HeaderSeparator => "|",
+ TableBorderPart.HeaderRight => "|",
+ TableBorderPart.HeaderBottomLeft => "|",
+ TableBorderPart.HeaderBottom => "-",
+ TableBorderPart.HeaderBottomSeparator => "|",
+ TableBorderPart.HeaderBottomRight => "|",
+ TableBorderPart.CellLeft => "|",
+ TableBorderPart.CellSeparator => "|",
+ TableBorderPart.CellRight => "|",
+ TableBorderPart.FooterBottomLeft => " ",
+ TableBorderPart.FooterBottom => " ",
+ TableBorderPart.FooterBottomSeparator => " ",
+ TableBorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+
+ ///
+ public override string GetColumnRow(TablePart part, IReadOnlyList widths, IReadOnlyList columns)
+ {
+ if (part != TablePart.Separator)
+ {
+ return base.GetColumnRow(part, widths, columns);
+ }
+
+ var (left, center, separator, right) = GetTableParts(part);
+
+ var builder = new StringBuilder();
+ builder.Append(left);
+
+ foreach (var (columnIndex, _, lastColumn, columnWidth) in widths.Enumerate())
+ {
+ var padding = columns[columnIndex].Padding;
+
+ if (padding.Left > 0)
+ {
+ // Left padding
+ builder.Append(" ".Multiply(padding.Left));
+ }
+
+ var justification = columns[columnIndex].Alignment;
+ if (justification == null)
+ {
+ // No alignment
+ builder.Append(center.Multiply(columnWidth));
+ }
+ else if (justification.Value == Justify.Left)
+ {
+ // Left
+ builder.Append(':');
+ builder.Append(center.Multiply(columnWidth - 1));
+ }
+ else if (justification.Value == Justify.Center)
+ {
+ // Centered
+ builder.Append(':');
+ builder.Append(center.Multiply(columnWidth - 2));
+ builder.Append(':');
+ }
+ else if (justification.Value == Justify.Right)
+ {
+ // Right
+ builder.Append(center.Multiply(columnWidth - 1));
+ builder.Append(':');
+ }
+
+ // Right padding
+ if (padding.Right > 0)
+ {
+ builder.Append(" ".Multiply(padding.Right));
+ }
+
+ if (!lastColumn)
+ {
+ builder.Append(separator);
+ }
+ }
+
+ builder.Append(right);
+ return builder.ToString();
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/MinimalDoubleHeadTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/MinimalDoubleHeadTableBorder.cs
new file mode 100644
index 0000000..86b5872
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/MinimalDoubleHeadTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a minimal border with a double header border.
+ ///
+ public sealed class MinimalDoubleHeadTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => " ",
+ TableBorderPart.HeaderTop => " ",
+ TableBorderPart.HeaderTopSeparator => " ",
+ TableBorderPart.HeaderTopRight => " ",
+ TableBorderPart.HeaderLeft => " ",
+ TableBorderPart.HeaderSeparator => "│",
+ TableBorderPart.HeaderRight => " ",
+ TableBorderPart.HeaderBottomLeft => " ",
+ TableBorderPart.HeaderBottom => "═",
+ TableBorderPart.HeaderBottomSeparator => "╪",
+ TableBorderPart.HeaderBottomRight => " ",
+ TableBorderPart.CellLeft => " ",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => " ",
+ TableBorderPart.FooterBottomLeft => " ",
+ TableBorderPart.FooterBottom => " ",
+ TableBorderPart.FooterBottomSeparator => " ",
+ TableBorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/MinimalHeavyHeadTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/MinimalHeavyHeadTableBorder.cs
new file mode 100644
index 0000000..a6da029
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/MinimalHeavyHeadTableBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a minimal border with a heavy header.
+ ///
+ public sealed class MinimalHeavyHeadTableBorder : TableBorder
+ {
+ ///
+ public override TableBorder? SafeBorder => TableBorder.Minimal;
+
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => " ",
+ TableBorderPart.HeaderTop => " ",
+ TableBorderPart.HeaderTopSeparator => " ",
+ TableBorderPart.HeaderTopRight => " ",
+ TableBorderPart.HeaderLeft => " ",
+ TableBorderPart.HeaderSeparator => "│",
+ TableBorderPart.HeaderRight => " ",
+ TableBorderPart.HeaderBottomLeft => " ",
+ TableBorderPart.HeaderBottom => "━",
+ TableBorderPart.HeaderBottomSeparator => "┿",
+ TableBorderPart.HeaderBottomRight => " ",
+ TableBorderPart.CellLeft => " ",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => " ",
+ TableBorderPart.FooterBottomLeft => " ",
+ TableBorderPart.FooterBottom => " ",
+ TableBorderPart.FooterBottomSeparator => " ",
+ TableBorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/MinimalTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/MinimalTableBorder.cs
new file mode 100644
index 0000000..48741a9
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/MinimalTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a minimal border.
+ ///
+ public sealed class MinimalTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => " ",
+ TableBorderPart.HeaderTop => " ",
+ TableBorderPart.HeaderTopSeparator => " ",
+ TableBorderPart.HeaderTopRight => " ",
+ TableBorderPart.HeaderLeft => " ",
+ TableBorderPart.HeaderSeparator => "│",
+ TableBorderPart.HeaderRight => " ",
+ TableBorderPart.HeaderBottomLeft => " ",
+ TableBorderPart.HeaderBottom => "─",
+ TableBorderPart.HeaderBottomSeparator => "┼",
+ TableBorderPart.HeaderBottomRight => " ",
+ TableBorderPart.CellLeft => " ",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => " ",
+ TableBorderPart.FooterBottomLeft => " ",
+ TableBorderPart.FooterBottom => " ",
+ TableBorderPart.FooterBottomSeparator => " ",
+ TableBorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Borders/NoBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/NoTableBorder.cs
similarity index 69%
rename from src/Spectre.Console/Borders/NoBorder.cs
rename to src/Spectre.Console/Rendering/Borders/Tables/NoTableBorder.cs
index 2350e7d..4153553 100644
--- a/src/Spectre.Console/Borders/NoBorder.cs
+++ b/src/Spectre.Console/Rendering/Borders/Tables/NoTableBorder.cs
@@ -3,13 +3,13 @@ namespace Spectre.Console.Rendering
///
/// Represents an invisible border.
///
- public sealed class NoBorder : Border
+ public sealed class NoTableBorder : TableBorder
{
///
public override bool Visible => false;
///
- protected override string GetBoxPart(BorderPart part)
+ protected override string GetBorderPart(TableBorderPart part)
{
return " ";
}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/RoundedTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/RoundedTableBorder.cs
new file mode 100644
index 0000000..dbdff51
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/RoundedTableBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a rounded border.
+ ///
+ public sealed class RoundedTableBorder : TableBorder
+ {
+ ///
+ public override TableBorder? SafeBorder => TableBorder.Square;
+
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "╭",
+ TableBorderPart.HeaderTop => "─",
+ TableBorderPart.HeaderTopSeparator => "┬",
+ TableBorderPart.HeaderTopRight => "╮",
+ TableBorderPart.HeaderLeft => "│",
+ TableBorderPart.HeaderSeparator => "│",
+ TableBorderPart.HeaderRight => "│",
+ TableBorderPart.HeaderBottomLeft => "├",
+ TableBorderPart.HeaderBottom => "─",
+ TableBorderPart.HeaderBottomSeparator => "┼",
+ TableBorderPart.HeaderBottomRight => "┤",
+ TableBorderPart.CellLeft => "│",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => "│",
+ TableBorderPart.FooterBottomLeft => "╰",
+ TableBorderPart.FooterBottom => "─",
+ TableBorderPart.FooterBottomSeparator => "┴",
+ TableBorderPart.FooterBottomRight => "╯",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/SimpleHeavyTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/SimpleHeavyTableBorder.cs
new file mode 100644
index 0000000..dbe2a93
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/SimpleHeavyTableBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a simple border with heavy lines.
+ ///
+ public sealed class SimpleHeavyTableBorder : TableBorder
+ {
+ ///
+ public override TableBorder? SafeBorder => TableBorder.Simple;
+
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => " ",
+ TableBorderPart.HeaderTop => " ",
+ TableBorderPart.HeaderTopSeparator => " ",
+ TableBorderPart.HeaderTopRight => " ",
+ TableBorderPart.HeaderLeft => " ",
+ TableBorderPart.HeaderSeparator => " ",
+ TableBorderPart.HeaderRight => " ",
+ TableBorderPart.HeaderBottomLeft => "━",
+ TableBorderPart.HeaderBottom => "━",
+ TableBorderPart.HeaderBottomSeparator => "━",
+ TableBorderPart.HeaderBottomRight => "━",
+ TableBorderPart.CellLeft => " ",
+ TableBorderPart.CellSeparator => " ",
+ TableBorderPart.CellRight => " ",
+ TableBorderPart.FooterBottomLeft => " ",
+ TableBorderPart.FooterBottom => " ",
+ TableBorderPart.FooterBottomSeparator => " ",
+ TableBorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/SimpleTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/SimpleTableBorder.cs
new file mode 100644
index 0000000..5ca7711
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/SimpleTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a simple border.
+ ///
+ public sealed class SimpleTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => " ",
+ TableBorderPart.HeaderTop => " ",
+ TableBorderPart.HeaderTopSeparator => " ",
+ TableBorderPart.HeaderTopRight => " ",
+ TableBorderPart.HeaderLeft => " ",
+ TableBorderPart.HeaderSeparator => " ",
+ TableBorderPart.HeaderRight => " ",
+ TableBorderPart.HeaderBottomLeft => "─",
+ TableBorderPart.HeaderBottom => "─",
+ TableBorderPart.HeaderBottomSeparator => "─",
+ TableBorderPart.HeaderBottomRight => "─",
+ TableBorderPart.CellLeft => " ",
+ TableBorderPart.CellSeparator => " ",
+ TableBorderPart.CellRight => " ",
+ TableBorderPart.FooterBottomLeft => " ",
+ TableBorderPart.FooterBottom => " ",
+ TableBorderPart.FooterBottomSeparator => " ",
+ TableBorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/Tables/SquareTableBorder.cs b/src/Spectre.Console/Rendering/Borders/Tables/SquareTableBorder.cs
new file mode 100644
index 0000000..e6582b0
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Tables/SquareTableBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a square border.
+ ///
+ public sealed class SquareTableBorder : TableBorder
+ {
+ ///
+ protected override string GetBorderPart(TableBorderPart part)
+ {
+ return part switch
+ {
+ TableBorderPart.HeaderTopLeft => "┌",
+ TableBorderPart.HeaderTop => "─",
+ TableBorderPart.HeaderTopSeparator => "┬",
+ TableBorderPart.HeaderTopRight => "┐",
+ TableBorderPart.HeaderLeft => "│",
+ TableBorderPart.HeaderSeparator => "│",
+ TableBorderPart.HeaderRight => "│",
+ TableBorderPart.HeaderBottomLeft => "├",
+ TableBorderPart.HeaderBottom => "─",
+ TableBorderPart.HeaderBottomSeparator => "┼",
+ TableBorderPart.HeaderBottomRight => "┤",
+ TableBorderPart.CellLeft => "│",
+ TableBorderPart.CellSeparator => "│",
+ TableBorderPart.CellRight => "│",
+ TableBorderPart.FooterBottomLeft => "└",
+ TableBorderPart.FooterBottom => "─",
+ TableBorderPart.FooterBottomSeparator => "┴",
+ TableBorderPart.FooterBottomRight => "┘",
+ _ => throw new InvalidOperationException("Unknown border part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/TablePart.cs b/src/Spectre.Console/Rendering/TablePart.cs
new file mode 100644
index 0000000..6c86d01
--- /dev/null
+++ b/src/Spectre.Console/Rendering/TablePart.cs
@@ -0,0 +1,23 @@
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents different parts of a table.
+ ///
+ public enum TablePart
+ {
+ ///
+ /// The top of a table.
+ ///
+ Top,
+
+ ///
+ /// The separator between the header and the cells.
+ ///
+ Separator,
+
+ ///
+ /// The bottom of a table.
+ ///
+ Bottom,
+ }
+}
diff --git a/src/Spectre.Console/Spectre.Console.csproj b/src/Spectre.Console/Spectre.Console.csproj
index cdb627d..aa72927 100644
--- a/src/Spectre.Console/Spectre.Console.csproj
+++ b/src/Spectre.Console/Spectre.Console.csproj
@@ -1,4 +1,4 @@
-
+
netstandard2.0
@@ -14,12 +14,15 @@
AnsiConsole.cs
-
- Color.cs
-
Border.cs
+
+ BoxBorder.cs
+
+
+ Color.cs
+
Emoji.cs
@@ -39,6 +42,12 @@
+
+ BoxBorder.cs
+
+
+ TableBorder.cs
+
AnsiConsoleExtensions.cs
diff --git a/src/Spectre.Console/Border.Known.cs b/src/Spectre.Console/TableBorder.Known.cs
similarity index 51%
rename from src/Spectre.Console/Border.Known.cs
rename to src/Spectre.Console/TableBorder.Known.cs
index 4bbf125..248d93c 100644
--- a/src/Spectre.Console/Border.Known.cs
+++ b/src/Spectre.Console/TableBorder.Known.cs
@@ -6,92 +6,97 @@ namespace Spectre.Console
///
/// Represents a border.
///
- public abstract partial class Border
+ public abstract partial class TableBorder
{
///
/// Gets an invisible border.
///
- public static Border None { get; } = new NoBorder();
+ public static TableBorder None { get; } = new NoTableBorder();
///
/// Gets an ASCII border.
///
- public static Border Ascii { get; } = new AsciiBorder();
+ public static TableBorder Ascii { get; } = new AsciiTableBorder();
///
- /// Gets another ASCII border.
+ /// Gets an ASCII border.
///
- public static Border Ascii2 { get; } = new Ascii2Border();
+ public static TableBorder Ascii2 { get; } = new Ascii2TableBorder();
///
/// Gets an ASCII border with a double header border.
///
- public static Border AsciiDoubleHead { get; } = new AsciiDoubleHeadBorder();
+ public static TableBorder AsciiDoubleHead { get; } = new AsciiDoubleHeadTableBorder();
///
/// Gets a square border.
///
- public static Border Square { get; } = new SquareBorder();
+ public static TableBorder Square { get; } = new SquareTableBorder();
///
/// Gets a rounded border.
///
- public static Border Rounded { get; } = new RoundedBorder();
+ public static TableBorder Rounded { get; } = new RoundedTableBorder();
///
/// Gets a minimal border.
///
- public static Border Minimal { get; } = new MinimalBorder();
+ public static TableBorder Minimal { get; } = new MinimalTableBorder();
///
/// Gets a minimal border with a heavy head.
///
- public static Border MinimalHeavyHead { get; } = new MinimalHeavyHeadBorder();
+ public static TableBorder MinimalHeavyHead { get; } = new MinimalHeavyHeadTableBorder();
///
/// Gets a minimal border with a double header border.
///
- public static Border MinimalDoubleHead { get; } = new MinimalDoubleHeadBorder();
+ public static TableBorder MinimalDoubleHead { get; } = new MinimalDoubleHeadTableBorder();
///
/// Gets a simple border.
///
- public static Border Simple { get; } = new SimpleBorder();
+ public static TableBorder Simple { get; } = new SimpleTableBorder();
///
/// Gets a simple border with heavy lines.
///
- public static Border SimpleHeavy { get; } = new SimpleHeavyBorder();
+ public static TableBorder SimpleHeavy { get; } = new SimpleHeavyTableBorder();
///
/// Gets a horizontal border.
///
- public static Border Horizontal { get; } = new HorizontalBorder();
+ public static TableBorder Horizontal { get; } = new HorizontalTableBorder();
///
/// Gets a heavy border.
///
- public static Border Heavy { get; } = new HeavyBorder();
+ public static TableBorder Heavy { get; } = new HeavyTableBorder();
///
/// Gets a border with a heavy edge.
///
- public static Border HeavyEdge { get; } = new HeavyEdgeBorder();
+ public static TableBorder HeavyEdge { get; } = new HeavyEdgeTableBorder();
///
/// Gets a border with a heavy header.
///
- public static Border HeavyHead { get; } = new HeavyHeadBorder();
+ public static TableBorder HeavyHead { get; } = new HeavyHeadTableBorder();
///
/// Gets a double border.
///
[SuppressMessage("Naming", "CA1720:Identifier contains type name")]
- public static Border Double { get; } = new DoubleBorder();
+ public static TableBorder Double { get; } = new DoubleTableBorder();
///
/// Gets a border with a double edge.
///
- public static Border DoubleEdge { get; } = new DoubleEdgeBorder();
+ public static TableBorder DoubleEdge { get; } = new DoubleEdgeTableBorder();
+
+ ///
+ /// Gets a markdown border.
+ ///
+ public static TableBorder Markdown { get; } = new MarkdownTableBorder();
}
}
diff --git a/src/Spectre.Console/TableBorder.cs b/src/Spectre.Console/TableBorder.cs
new file mode 100644
index 0000000..cb2c21b
--- /dev/null
+++ b/src/Spectre.Console/TableBorder.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Spectre.Console.Internal;
+using Spectre.Console.Rendering;
+
+namespace Spectre.Console
+{
+ ///
+ /// Represents a border.
+ ///
+ public abstract partial class TableBorder
+ {
+ private readonly Dictionary _lookup;
+
+ ///
+ /// Gets a value indicating whether or not the border is visible.
+ ///
+ public virtual bool Visible { get; } = true;
+
+ ///
+ /// Gets the safe border for this border or null if none exist.
+ ///
+ public virtual TableBorder? SafeBorder { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected TableBorder()
+ {
+ _lookup = Initialize();
+ }
+
+ private Dictionary Initialize()
+ {
+ var lookup = new Dictionary();
+ foreach (TableBorderPart? part in Enum.GetValues(typeof(TableBorderPart)))
+ {
+ if (part == null)
+ {
+ continue;
+ }
+
+ var text = GetBorderPart(part.Value);
+ if (text.Length > 1)
+ {
+ throw new InvalidOperationException("A box part cannot contain more than one character.");
+ }
+
+ lookup.Add(part.Value, GetBorderPart(part.Value));
+ }
+
+ return lookup;
+ }
+
+ ///
+ /// Gets the string representation of a specific border part.
+ ///
+ /// The part to get a string representation for.
+ /// The number of repetitions.
+ /// A string representation of the specified border part.
+ public string GetPart(TableBorderPart part, int count)
+ {
+ // TODO: This need some optimization...
+ return string.Join(string.Empty, Enumerable.Repeat(GetBorderPart(part)[0], count));
+ }
+
+ ///
+ /// Gets a whole column row for the specific column row part.
+ ///
+ /// The column row part.
+ /// The column widths.
+ /// The columns.
+ /// A string representing the column row.
+ public virtual string GetColumnRow(TablePart part, IReadOnlyList widths, IReadOnlyList columns)
+ {
+ if (widths is null)
+ {
+ throw new ArgumentNullException(nameof(widths));
+ }
+
+ if (columns is null)
+ {
+ throw new ArgumentNullException(nameof(columns));
+ }
+
+ var (left, center, separator, right) = GetTableParts(part);
+
+ var builder = new StringBuilder();
+ builder.Append(left);
+
+ foreach (var (columnIndex, _, lastColumn, columnWidth) in widths.Enumerate())
+ {
+ var padding = columns[columnIndex].Padding;
+ var centerWidth = padding.Left + columnWidth + padding.Right;
+ builder.Append(center.Multiply(centerWidth));
+
+ if (!lastColumn)
+ {
+ builder.Append(separator);
+ }
+ }
+
+ builder.Append(right);
+ return builder.ToString();
+ }
+
+ ///
+ /// Gets the string representation of a specific border part.
+ ///
+ /// The part to get a string representation for.
+ /// A string representation of the specified border part.
+ public string GetPart(TableBorderPart part)
+ {
+ return _lookup[part].ToString(CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Gets the character representing the specified border part.
+ ///
+ /// The part to get the character representation for.
+ /// A character representation of the specified border part.
+ protected abstract string GetBorderPart(TableBorderPart part);
+
+ ///
+ /// Gets the table parts used to render a specific table row.
+ ///
+ /// The table part.
+ /// The table parts used to render the specific table row.
+ protected (string Left, string Center, string Separator, string Right)
+ GetTableParts(TablePart part)
+ {
+ return part switch
+ {
+ // Top part
+ TablePart.Top =>
+ (GetPart(TableBorderPart.HeaderTopLeft), GetPart(TableBorderPart.HeaderTop),
+ GetPart(TableBorderPart.HeaderTopSeparator), GetPart(TableBorderPart.HeaderTopRight)),
+
+ // Separator between header and cells
+ TablePart.Separator =>
+ (GetPart(TableBorderPart.HeaderBottomLeft), GetPart(TableBorderPart.HeaderBottom),
+ GetPart(TableBorderPart.HeaderBottomSeparator), GetPart(TableBorderPart.HeaderBottomRight)),
+
+ // Bottom part
+ TablePart.Bottom =>
+ (GetPart(TableBorderPart.FooterBottomLeft), GetPart(TableBorderPart.FooterBottom),
+ GetPart(TableBorderPart.FooterBottomSeparator), GetPart(TableBorderPart.FooterBottomRight)),
+
+ // Unknown
+ _ => throw new NotSupportedException("Unknown column row part"),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Widgets/Grid.cs b/src/Spectre.Console/Widgets/Grid.cs
index 3a7d1a1..4fe9181 100644
--- a/src/Spectre.Console/Widgets/Grid.cs
+++ b/src/Spectre.Console/Widgets/Grid.cs
@@ -35,7 +35,7 @@ namespace Spectre.Console
{
_table = new Table
{
- Border = Border.None,
+ Border = TableBorder.None,
ShowHeaders = false,
IsGrid = true,
PadRightCell = false,
diff --git a/src/Spectre.Console/Widgets/Panel.cs b/src/Spectre.Console/Widgets/Panel.cs
index c4ae217..efe4c88 100644
--- a/src/Spectre.Console/Widgets/Panel.cs
+++ b/src/Spectre.Console/Widgets/Panel.cs
@@ -8,14 +8,14 @@ namespace Spectre.Console
///
/// A renderable panel.
///
- public sealed class Panel : Renderable, IHasBorder, IExpandable, IPaddable
+ public sealed class Panel : Renderable, IHasBoxBorder, IExpandable, IPaddable
{
private const int EdgeWidth = 2;
private readonly IRenderable _child;
///
- public Border Border { get; set; } = Border.Square;
+ public BoxBorder Border { get; set; } = BoxBorder.Square;
///
public bool UseSafeBorder { get; set; } = true;
@@ -95,7 +95,7 @@ namespace Spectre.Console
var childSegments = ((IRenderable)child).Render(context, childWidth);
foreach (var line in Segment.SplitLines(childSegments, panelWidth))
{
- result.Add(new Segment(border.GetPart(BorderPart.CellLeft), borderStyle));
+ result.Add(new Segment(border.GetPart(BoxBorderPart.Left), borderStyle));
var content = new List();
content.AddRange(line);
@@ -110,7 +110,7 @@ namespace Spectre.Console
result.AddRange(content);
- result.Add(new Segment(border.GetPart(BorderPart.CellRight), borderStyle));
+ result.Add(new Segment(border.GetPart(BoxBorderPart.Right), borderStyle));
result.Add(Segment.LineBreak);
}
@@ -120,17 +120,17 @@ namespace Spectre.Console
return result;
}
- private static void AddBottomBorder(List result, Border border, Style borderStyle, int panelWidth)
+ private static void AddBottomBorder(List result, BoxBorder border, Style borderStyle, int panelWidth)
{
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottomLeft), borderStyle));
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, panelWidth - EdgeWidth), borderStyle));
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottomRight), borderStyle));
+ result.Add(new Segment(border.GetPart(BoxBorderPart.BottomLeft), borderStyle));
+ result.Add(new Segment(border.GetPart(BoxBorderPart.Bottom, panelWidth - EdgeWidth), borderStyle));
+ result.Add(new Segment(border.GetPart(BoxBorderPart.BottomRight), borderStyle));
result.Add(Segment.LineBreak);
}
- private void AddTopBorder(List segments, RenderContext context, Border border, Style borderStyle, int panelWidth)
+ private void AddTopBorder(List segments, RenderContext context, BoxBorder border, Style borderStyle, int panelWidth)
{
- segments.Add(new Segment(border.GetPart(BorderPart.HeaderTopLeft), borderStyle));
+ segments.Add(new Segment(border.GetPart(BoxBorderPart.TopLeft), borderStyle));
if (Header != null)
{
@@ -160,16 +160,16 @@ namespace Spectre.Console
}
}
- segments.Add(new Segment(border.GetPart(BorderPart.HeaderTop, leftSpacing + 1), borderStyle));
+ segments.Add(new Segment(border.GetPart(BoxBorderPart.Top, leftSpacing + 1), borderStyle));
segments.Add(header);
- segments.Add(new Segment(border.GetPart(BorderPart.HeaderTop, rightSpacing + 1), borderStyle));
+ segments.Add(new Segment(border.GetPart(BoxBorderPart.Top, rightSpacing + 1), borderStyle));
}
else
{
- segments.Add(new Segment(border.GetPart(BorderPart.HeaderTop, panelWidth - EdgeWidth), borderStyle));
+ segments.Add(new Segment(border.GetPart(BoxBorderPart.Top, panelWidth - EdgeWidth), borderStyle));
}
- segments.Add(new Segment(border.GetPart(BorderPart.HeaderTopRight), borderStyle));
+ segments.Add(new Segment(border.GetPart(BoxBorderPart.TopRight), borderStyle));
segments.Add(Segment.LineBreak);
}
}
diff --git a/src/Spectre.Console/Widgets/Table.cs b/src/Spectre.Console/Widgets/Table.cs
index 827a440..f6d723d 100644
--- a/src/Spectre.Console/Widgets/Table.cs
+++ b/src/Spectre.Console/Widgets/Table.cs
@@ -9,7 +9,7 @@ namespace Spectre.Console
///
/// A renderable table.
///
- public sealed class Table : Renderable, IHasBorder, IExpandable
+ public sealed class Table : Renderable, IHasTableBorder, IExpandable
{
private const int EdgeCount = 2;
@@ -27,7 +27,7 @@ namespace Spectre.Console
public int RowCount => _rows.Count;
///
- public Border Border { get; set; } = Border.Square;
+ public TableBorder Border { get; set; } = TableBorder.Square;
///
public Style? BorderStyle { get; set; }
@@ -202,22 +202,8 @@ namespace Spectre.Console
// Show top of header?
if (firstRow && showBorder)
{
- result.Add(new Segment(border.GetPart(BorderPart.HeaderTopLeft), borderStyle));
- foreach (var (columnIndex, _, lastColumn, columnWidth) in columnWidths.Enumerate())
- {
- var padding = _columns[columnIndex].Padding;
-
- result.Add(new Segment(border.GetPart(BorderPart.HeaderTop, padding.Left), borderStyle)); // Left padding
- result.Add(new Segment(border.GetPart(BorderPart.HeaderTop, columnWidth), borderStyle));
- result.Add(new Segment(border.GetPart(BorderPart.HeaderTop, padding.Right), borderStyle)); // Right padding
-
- if (!lastColumn)
- {
- result.Add(new Segment(border.GetPart(BorderPart.HeaderTopSeparator), borderStyle));
- }
- }
-
- result.Add(new Segment(border.GetPart(BorderPart.HeaderTopRight), borderStyle));
+ var separator = border.GetColumnRow(TablePart.Top, columnWidths, _columns);
+ result.Add(new Segment(separator, borderStyle));
result.Add(Segment.LineBreak);
}
@@ -232,7 +218,7 @@ namespace Spectre.Console
if (firstCell && showBorder)
{
// Show left column edge
- var part = firstRow && ShowHeaders ? BorderPart.HeaderLeft : BorderPart.CellLeft;
+ var part = firstRow && ShowHeaders ? TableBorderPart.HeaderLeft : TableBorderPart.CellLeft;
result.Add(new Segment(border.GetPart(part), borderStyle));
}
@@ -269,13 +255,13 @@ namespace Spectre.Console
if (lastCell && showBorder)
{
// Add right column edge
- var part = firstRow && ShowHeaders ? BorderPart.HeaderRight : BorderPart.CellRight;
+ var part = firstRow && ShowHeaders ? TableBorderPart.HeaderRight : TableBorderPart.CellRight;
result.Add(new Segment(border.GetPart(part), borderStyle));
}
else if (showBorder)
{
// Add column separator
- var part = firstRow && ShowHeaders ? BorderPart.HeaderSeparator : BorderPart.CellSeparator;
+ var part = firstRow && ShowHeaders ? TableBorderPart.HeaderSeparator : TableBorderPart.CellSeparator;
result.Add(new Segment(border.GetPart(part), borderStyle));
}
}
@@ -286,44 +272,16 @@ namespace Spectre.Console
// Show header separator?
if (firstRow && showBorder && ShowHeaders && hasRows)
{
- result.Add(new Segment(border.GetPart(BorderPart.HeaderBottomLeft), borderStyle));
- foreach (var (columnIndex, first, lastColumn, columnWidth) in columnWidths.Enumerate())
- {
- var padding = _columns[columnIndex].Padding;
-
- result.Add(new Segment(border.GetPart(BorderPart.HeaderBottom, padding.Left), borderStyle)); // Left padding
- result.Add(new Segment(border.GetPart(BorderPart.HeaderBottom, columnWidth), borderStyle));
- result.Add(new Segment(border.GetPart(BorderPart.HeaderBottom, padding.Right), borderStyle)); // Right padding
-
- if (!lastColumn)
- {
- result.Add(new Segment(border.GetPart(BorderPart.HeaderBottomSeparator), borderStyle));
- }
- }
-
- result.Add(new Segment(border.GetPart(BorderPart.HeaderBottomRight), borderStyle));
+ var separator = border.GetColumnRow(TablePart.Separator, columnWidths, _columns);
+ result.Add(new Segment(separator, borderStyle));
result.Add(Segment.LineBreak);
}
// Show bottom of footer?
if (lastRow && showBorder)
{
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottomLeft), borderStyle));
- foreach (var (columnIndex, first, lastColumn, columnWidth) in columnWidths.Enumerate())
- {
- var padding = _columns[columnIndex].Padding;
-
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, padding.Left), borderStyle)); // Left padding
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, columnWidth), borderStyle));
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottom, padding.Right), borderStyle)); // Right padding
-
- if (!lastColumn)
- {
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottomSeparator), borderStyle));
- }
- }
-
- result.Add(new Segment(border.GetPart(BorderPart.FooterBottomRight), borderStyle));
+ var separator = border.GetColumnRow(TablePart.Bottom, columnWidths, _columns);
+ result.Add(new Segment(separator, borderStyle));
result.Add(Segment.LineBreak);
}
}