diff --git a/src/Spectre.Console.Tests/Unit/MarkupTests.cs b/src/Spectre.Console.Tests/Unit/MarkupTests.cs
index 2e571c9..54b3564 100644
--- a/src/Spectre.Console.Tests/Unit/MarkupTests.cs
+++ b/src/Spectre.Console.Tests/Unit/MarkupTests.cs
@@ -7,6 +7,44 @@ namespace Spectre.Console.Tests.Unit
{
public sealed class MarkupTests
{
+ public sealed class TheLengthProperty
+ {
+ [Theory]
+ [InlineData("Hello", 5)]
+ [InlineData("Hello\nWorld", 11)]
+ [InlineData("[yellow]Hello[/]", 5)]
+ public void Should_Return_The_Number_Of_Characters(string input, int expected)
+ {
+ // Given
+ var markup = new Markup(input);
+
+ // When
+ var result = markup.Length;
+
+ // Then
+ result.ShouldBe(expected);
+ }
+ }
+
+ public sealed class TheLinesProperty
+ {
+ [Theory]
+ [InlineData("Hello", 1)]
+ [InlineData("Hello\nWorld", 2)]
+ [InlineData("[yellow]Hello[/]\nWorld", 2)]
+ public void Should_Return_The_Number_Of_Lines(string input, int expected)
+ {
+ // Given
+ var markup = new Markup(input);
+
+ // When
+ var result = markup.Lines;
+
+ // Then
+ result.ShouldBe(expected);
+ }
+ }
+
public sealed class TheEscapeMethod
{
[Theory]
diff --git a/src/Spectre.Console.Tests/Unit/TextTests.cs b/src/Spectre.Console.Tests/Unit/TextTests.cs
index f630e64..34a27a8 100644
--- a/src/Spectre.Console.Tests/Unit/TextTests.cs
+++ b/src/Spectre.Console.Tests/Unit/TextTests.cs
@@ -7,6 +7,42 @@ namespace Spectre.Console.Tests.Unit
{
public sealed class TextTests
{
+ public sealed class TheLengthProperty
+ {
+ [Theory]
+ [InlineData("Hello", 5)]
+ [InlineData("Hello\nWorld", 11)]
+ public void Should_Return_The_Number_Of_Characters(string input, int expected)
+ {
+ // Given
+ var markup = new Text(input);
+
+ // When
+ var result = markup.Length;
+
+ // Then
+ result.ShouldBe(expected);
+ }
+ }
+
+ public sealed class TheLinesProperty
+ {
+ [Theory]
+ [InlineData("Hello", 1)]
+ [InlineData("Hello\nWorld", 2)]
+ public void Should_Return_The_Number_Of_Lines(string input, int expected)
+ {
+ // Given
+ var markup = new Text(input);
+
+ // When
+ var result = markup.Lines;
+
+ // Then
+ result.ShouldBe(expected);
+ }
+ }
+
[Fact]
public void Should_Consider_The_Longest_Word_As_Minimum_Width()
{
diff --git a/src/Spectre.Console/Cli/Internal/Composer.cs b/src/Spectre.Console/Cli/Internal/Composer.cs
index abdb3a3..962c1a1 100644
--- a/src/Spectre.Console/Cli/Internal/Composer.cs
+++ b/src/Spectre.Console/Cli/Internal/Composer.cs
@@ -71,7 +71,7 @@ namespace Spectre.Console.Cli
{
for (var i = 0; i < count; i++)
{
- _content.Append(Environment.NewLine);
+ _content.Append('\n');
}
return this;
diff --git a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Markup.cs b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Markup.cs
index 1f2f8a9..5e9000d 100644
--- a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Markup.cs
+++ b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.Markup.cs
@@ -59,7 +59,7 @@ namespace Spectre.Console
/// The value to write.
public static void MarkupLine(this IAnsiConsole console, string value)
{
- Markup(console, value + Environment.NewLine);
+ Markup(console, value + "\n");
}
///
@@ -71,7 +71,7 @@ namespace Spectre.Console
/// An array of objects to write.
public static void MarkupLine(this IAnsiConsole console, IFormatProvider provider, string format, params object[] args)
{
- Markup(console, provider, format + Environment.NewLine, args);
+ Markup(console, provider, format + "\n", args);
}
}
}
\ No newline at end of file
diff --git a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs
index b91b813..0f7c1be 100644
--- a/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs
+++ b/src/Spectre.Console/Extensions/AnsiConsoleExtensions.cs
@@ -73,7 +73,7 @@ namespace Spectre.Console
throw new ArgumentNullException(nameof(console));
}
- console.Write(new Text(Environment.NewLine, Style.Plain));
+ console.Write(new Text("\n", Style.Plain));
}
///
@@ -104,7 +104,7 @@ namespace Spectre.Console
throw new ArgumentNullException(nameof(text));
}
- console.Write(text + Environment.NewLine, style);
+ console.Write(text + "\n", style);
}
}
}
diff --git a/src/Spectre.Console/Extensions/StringExtensions.cs b/src/Spectre.Console/Extensions/StringExtensions.cs
index d7db267..4a08881 100644
--- a/src/Spectre.Console/Extensions/StringExtensions.cs
+++ b/src/Spectre.Console/Extensions/StringExtensions.cs
@@ -11,11 +11,6 @@ namespace Spectre.Console
///
public 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);
-
///
/// Escapes text so that it won’t be interpreted as markup.
///
@@ -91,12 +86,6 @@ namespace Spectre.Console
{
text = text?.ReplaceExact("\r\n", "\n");
text ??= string.Empty;
-
- if (native && !_alreadyNormalized)
- {
- text = text.ReplaceExact("\n", Environment.NewLine);
- }
-
return text;
}
diff --git a/src/Spectre.Console/Internal/Backends/Ansi/AnsiBuilder.cs b/src/Spectre.Console/Internal/Backends/Ansi/AnsiBuilder.cs
index e30923a..ef8267a 100644
--- a/src/Spectre.Console/Internal/Backends/Ansi/AnsiBuilder.cs
+++ b/src/Spectre.Console/Internal/Backends/Ansi/AnsiBuilder.cs
@@ -36,7 +36,7 @@ namespace Spectre.Console
if (!last)
{
- builder.Append(Environment.NewLine);
+ builder.Append('\n');
}
}
}
diff --git a/src/Spectre.Console/Rendering/Segment.cs b/src/Spectre.Console/Rendering/Segment.cs
index ad2fb63..1984f8a 100644
--- a/src/Spectre.Console/Rendering/Segment.cs
+++ b/src/Spectre.Console/Rendering/Segment.cs
@@ -44,7 +44,7 @@ namespace Spectre.Console.Rendering
///
/// Gets a segment representing a line break.
///
- public static Segment LineBreak { get; } = new Segment(Environment.NewLine, Style.Plain, true, false);
+ public static Segment LineBreak { get; } = new Segment("\n", Style.Plain, true, false);
///
/// Gets an empty segment.
diff --git a/src/Spectre.Console/Widgets/Markup.cs b/src/Spectre.Console/Widgets/Markup.cs
index d52ca32..5dc0e5c 100644
--- a/src/Spectre.Console/Widgets/Markup.cs
+++ b/src/Spectre.Console/Widgets/Markup.cs
@@ -27,6 +27,16 @@ namespace Spectre.Console
set => _paragraph.Overflow = value;
}
+ ///
+ /// Gets the character count.
+ ///
+ public int Length => _paragraph.Length;
+
+ ///
+ /// Gets the number of lines.
+ ///
+ public int Lines => _paragraph.Lines;
+
///
/// Initializes a new instance of the class.
///
diff --git a/src/Spectre.Console/Widgets/Paragraph.cs b/src/Spectre.Console/Widgets/Paragraph.cs
index c6a2abf..78f4bb1 100644
--- a/src/Spectre.Console/Widgets/Paragraph.cs
+++ b/src/Spectre.Console/Widgets/Paragraph.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Text;
using Spectre.Console.Rendering;
namespace Spectre.Console
@@ -25,6 +26,16 @@ namespace Spectre.Console
///
public Overflow? Overflow { get; set; }
+ ///
+ /// Gets the character count of the paragraph.
+ ///
+ public int Length => _lines.Sum(line => line.Length) + Math.Max(0, Lines - 1);
+
+ ///
+ /// Gets the number of lines in the paragraph.
+ ///
+ public int Lines => _lines.Count;
+
///
/// Initializes a new instance of the class.
///
diff --git a/src/Spectre.Console/Widgets/Progress/Renderers/FallbackStatusRenderer.cs b/src/Spectre.Console/Widgets/Progress/Renderers/FallbackStatusRenderer.cs
index 4b10c10..f5a380b 100644
--- a/src/Spectre.Console/Widgets/Progress/Renderers/FallbackStatusRenderer.cs
+++ b/src/Spectre.Console/Widgets/Progress/Renderers/FallbackStatusRenderer.cs
@@ -29,7 +29,7 @@ namespace Spectre.Console
if (_lastStatus != task.Description)
{
_lastStatus = task.Description;
- _renderable = new Markup(task.Description + Environment.NewLine);
+ _renderable = new Markup(task.Description + "\n");
return;
}
}
diff --git a/src/Spectre.Console/Widgets/Text.cs b/src/Spectre.Console/Widgets/Text.cs
index bb60f5e..3ff232c 100644
--- a/src/Spectre.Console/Widgets/Text.cs
+++ b/src/Spectre.Console/Widgets/Text.cs
@@ -47,6 +47,16 @@ namespace Spectre.Console
set => _paragraph.Overflow = value;
}
+ ///
+ /// Gets the character count.
+ ///
+ public int Length => _paragraph.Length;
+
+ ///
+ /// Gets the number of lines in the text.
+ ///
+ public int Lines => _paragraph.Lines;
+
///
protected override Measurement Measure(RenderContext context, int maxWidth)
{