Change IAnsiConsole to render IRenderable

This makes it possible for encoders to output better representation
of the actual objects instead of working with chopped up segments.

* IAnsiConsole.Write now takes an IRenderable instead of segments
* Calculating cell width does no longer require a render context
* Removed RenderContext.LegacyConsole
* Removed RenderContext.Encoding
* Added Capabilities.Unicode
This commit is contained in:
Patrik Svensson
2021-03-24 23:09:24 +01:00
committed by Phil Scott
parent 2ba6da3514
commit 20650f1e7e
75 changed files with 492 additions and 553 deletions

View File

@ -15,7 +15,7 @@ namespace Spectre.Console
/// <param name="format">The exception format options.</param>
public static void WriteException(this IAnsiConsole console, Exception exception, ExceptionFormats format = ExceptionFormats.Default)
{
Render(console, exception.GetRenderable(format));
console.Write(exception.GetRenderable(format));
}
/// <summary>
@ -26,7 +26,7 @@ namespace Spectre.Console
/// <param name="settings">The exception settings.</param>
public static void WriteException(this IAnsiConsole console, Exception exception, ExceptionSettings settings)
{
Render(console, exception.GetRenderable(settings));
console.Write(exception.GetRenderable(settings));
}
}
}

View File

@ -38,7 +38,7 @@ namespace Spectre.Console
/// <param name="value">The value to write.</param>
public static void Markup(this IAnsiConsole console, string value)
{
console.Render(MarkupParser.Parse(value));
console.Write(MarkupParser.Parse(value));
}
/// <summary>

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using Spectre.Console.Rendering;
namespace Spectre.Console
@ -14,6 +13,7 @@ namespace Spectre.Console
/// </summary>
/// <param name="console">The console to render to.</param>
/// <param name="renderable">The object to render.</param>
[Obsolete("Consider using IAnsiConsole.Write instead.")]
public static void Render(this IAnsiConsole console, IRenderable renderable)
{
if (console is null)
@ -26,21 +26,7 @@ namespace Spectre.Console
throw new ArgumentNullException(nameof(renderable));
}
var context = new RenderContext(console.Profile.Encoding, console.Profile.Capabilities.Legacy);
var renderables = console.Pipeline.Process(context, new[] { renderable });
Render(console, context, renderables);
}
private static void Render(IAnsiConsole console, RenderContext options, IEnumerable<IRenderable> renderables)
{
var result = new List<Segment>();
foreach (var renderable in renderables)
{
result.AddRange(renderable.Render(options, console.Profile.Width));
}
console.Write(Segment.Merge(result));
console.Write(renderable);
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using Spectre.Console.Rendering;
namespace Spectre.Console
{
@ -18,26 +17,6 @@ namespace Spectre.Console
return new Recorder(console);
}
/// <summary>
/// Writes the specified string value to the console.
/// </summary>
/// <param name="console">The console to write to.</param>
/// <param name="segment">The segment to write.</param>
public static void Write(this IAnsiConsole console, Segment segment)
{
if (console is null)
{
throw new ArgumentNullException(nameof(console));
}
if (segment is null)
{
throw new ArgumentNullException(nameof(segment));
}
console.Write(new[] { segment });
}
/// <summary>
/// Writes the specified string value to the console.
/// </summary>
@ -45,7 +24,7 @@ namespace Spectre.Console
/// <param name="text">The text to write.</param>
public static void Write(this IAnsiConsole console, string text)
{
Render(console, new Text(text, Style.Plain));
console.Write(new Text(text, Style.Plain));
}
/// <summary>
@ -56,7 +35,7 @@ namespace Spectre.Console
/// <param name="style">The text style.</param>
public static void Write(this IAnsiConsole console, string text, Style style)
{
Render(console, new Text(text, style));
console.Write(new Text(text, style));
}
/// <summary>
@ -70,7 +49,7 @@ namespace Spectre.Console
throw new ArgumentNullException(nameof(console));
}
Render(console, new Text(Environment.NewLine, Style.Plain));
console.Write(new Text(Environment.NewLine, Style.Plain));
}
/// <summary>

View File

@ -1,4 +1,5 @@
using System;
using Spectre.Console.Internal;
namespace Spectre.Console
{

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using Spectre.Console.Rendering;
namespace Spectre.Console
{
/// <summary>
/// Contains extension methods for <see cref="IRenderable"/>.
/// </summary>
public static class RenderableExtensions
{
/// <summary>
/// Gets the segments for a renderable using the specified console.
/// </summary>
/// <param name="renderable">The renderable.</param>
/// <param name="console">The console.</param>
/// <returns>An enumerable containing segments representing the specified <see cref="IRenderable"/>.</returns>
public static IEnumerable<Segment> GetSegments(this IRenderable renderable, IAnsiConsole console)
{
if (console is null)
{
throw new ArgumentNullException(nameof(console));
}
if (renderable is null)
{
throw new ArgumentNullException(nameof(renderable));
}
var context = new RenderContext(console.Profile.Capabilities);
var renderables = console.Pipeline.Process(context, new[] { renderable });
return GetSegments(console, context, renderables);
}
private static IEnumerable<Segment> GetSegments(IAnsiConsole console, RenderContext options, IEnumerable<IRenderable> renderables)
{
var result = new List<Segment>();
foreach (var renderable in renderables)
{
result.AddRange(renderable.Render(options, console.Profile.Width));
}
return Segment.Merge(result);
}
}
}

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Spectre.Console.Rendering;
namespace Spectre.Console
{
@ -60,14 +59,9 @@ namespace Spectre.Console
return result.ToString();
}
internal static int CellLength(this string text, RenderContext context)
internal static int CellLength(this string text)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}
return Cell.GetCellLength(context, text);
return Cell.GetCellLength(text);
}
internal static string CapitalizeFirstLetter(this string? text, CultureInfo? culture = null)