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) {