Merge segments before rendering

This will reduce the number of segments to render
and produce cleaner ANSI escape code sequences.

Closes #46
This commit is contained in:
Patrik Svensson 2020-08-30 12:33:49 +02:00 committed by Patrik Svensson
parent 47fd646d21
commit 7fd2efaeb5
4 changed files with 42 additions and 5 deletions

View File

@ -12,7 +12,7 @@ namespace Spectre.Console.Tests.Unit
{
[Theory]
[InlineData("[yellow]Hello[/]", "Hello")]
[InlineData("[yellow]Hello [italic]World[/]![/]", "Hello World!")]
[InlineData("[yellow]Hello [italic]World[/]![/]", "Hello World!")]
public void Should_Output_Expected_Ansi_For_Markup(string markup, string expected)
{
// Given
@ -26,7 +26,7 @@ namespace Spectre.Console.Tests.Unit
}
[Theory]
[InlineData("[yellow]Hello [[ World[/]", "Hello [ World")]
[InlineData("[yellow]Hello [[ World[/]", "Hello [ World")]
public void Should_Be_Able_To_Escape_Tags(string markup, string expected)
{
// Given

View File

@ -30,8 +30,11 @@ namespace Spectre.Console
using (console.PushStyle(Style.Plain))
{
var segments = renderable.Render(options, console.Width);
segments = Segment.Merge(segments);
var current = Style.Plain;
foreach (var segment in renderable.Render(options, console.Width))
foreach (var segment in segments)
{
if (string.IsNullOrEmpty(segment.Text))
{

View File

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

View File

@ -16,7 +16,7 @@ namespace Spectre.Console.Rendering
/// <summary>
/// Gets the segment text.
/// </summary>
public string Text { get; }
public string Text { get; internal set; }
/// <summary>
/// Gets a value indicating whether or not this is an expicit line break
@ -226,6 +226,41 @@ namespace Spectre.Console.Rendering
return lines;
}
internal static IEnumerable<Segment> Merge(IEnumerable<Segment> segments)
{
var result = new List<Segment>();
var previous = (Segment?)null;
foreach (var segment in segments)
{
if (previous == null)
{
previous = segment;
continue;
}
// Same style?
if (previous.Style.Equals(segment.Style))
{
// Modify the content of the previous segment
previous.Text += segment.Text;
}
else
{
// Push the current one to the results.
result.Add(previous);
previous = segment;
}
}
if (previous != null)
{
result.Add(previous);
}
return result;
}
internal static List<List<SegmentLine>> MakeSameHeight(int cellHeight, List<List<SegmentLine>> cells)
{
foreach (var cell in cells)