Added initial support for rendering composites

This is far from complete, but it's a start
and it will enable us to create things like tables
and other complex objects in the long run.
This commit is contained in:
Patrik Svensson
2020-07-29 17:34:54 +02:00
committed by Patrik Svensson
parent e596e6eb4f
commit 8e4f33bba4
41 changed files with 1164 additions and 24 deletions

View File

@ -0,0 +1,12 @@
using System.Text;
namespace Spectre.Console.Internal
{
internal static class CharExtensions
{
public static int CellLength(this char token, Encoding encoding)
{
return Cell.GetCellLength(encoding, token);
}
}
}

View File

@ -1,10 +1,25 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Spectre.Console.Composition;
namespace Spectre.Console.Internal
{
internal static class ConsoleExtensions
{
public static IDisposable PushAppearance(this IAnsiConsole console, Appearance appearance)
{
if (console is null)
{
throw new ArgumentNullException(nameof(console));
}
var current = new Appearance(console.Foreground, console.Background, console.Style);
console.SetColor(appearance.Foreground, true);
console.SetColor(appearance.Background, false);
console.Style = appearance.Style;
return new AppearanceScope(console, current);
}
public static IDisposable PushColor(this IAnsiConsole console, Color color, bool foreground)
{
if (console is null)
@ -47,6 +62,33 @@ namespace Spectre.Console.Internal
}
}
internal sealed class AppearanceScope : IDisposable
{
private readonly IAnsiConsole _console;
private readonly Appearance _apperance;
public AppearanceScope(IAnsiConsole console, Appearance appearance)
{
_console = console ?? throw new ArgumentNullException(nameof(console));
_apperance = appearance;
}
[SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations")]
[SuppressMessage("Performance", "CA1821:Remove empty Finalizers")]
~AppearanceScope()
{
throw new InvalidOperationException("Appearance scope was not disposed.");
}
public void Dispose()
{
GC.SuppressFinalize(this);
_console.SetColor(_apperance.Foreground, true);
_console.SetColor(_apperance.Background, false);
_console.Style = _apperance.Style;
}
}
internal sealed class ColorScope : IDisposable
{
private readonly IAnsiConsole _console;

View File

@ -0,0 +1,36 @@
using System;
using System.Text;
namespace Spectre.Console.Internal
{
internal static class StringExtensions
{
// Cache whether or not internally normalized line endings
// already are normalized. No reason to do yet another replace if it is.
private static readonly bool _alreadyNormalized
= Environment.NewLine.Equals("\n", StringComparison.OrdinalIgnoreCase);
public static int CellLength(this string text, Encoding encoding)
{
return Cell.GetCellLength(encoding, text);
}
public static string NormalizeLineEndings(this string text, bool native = false)
{
var normalized = text?.Replace("\r\n", "\n")
?.Replace("\r", string.Empty);
if (native && !_alreadyNormalized)
{
normalized = normalized.Replace("\n", Environment.NewLine);
}
return normalized;
}
public static string[] SplitLines(this string text)
{
return text.NormalizeLineEndings().Split(new[] { '\n' }, StringSplitOptions.None);
}
}
}