using System; using System.Collections.Generic; using System.Linq; using System.Text; using Spectre.Console.Internal; namespace Spectre.Console.Composition { /// /// Represents a renderable segment. /// public sealed class Segment { /// /// Gets the segment text. /// public string Text { get; } /// /// Gets the appearance of the segment. /// public Appearance Appearance { get; } /// /// Initializes a new instance of the class. /// /// The segment text. public Segment(string text) : this(text, Appearance.Plain) { } /// /// Initializes a new instance of the class. /// /// The segment text. /// The segment appearance. public Segment(string text, Appearance appearance) { Text = text?.NormalizeLineEndings() ?? throw new ArgumentNullException(nameof(text)); Appearance = appearance; } /// /// Gets the number of cells that this segment /// occupies in the console. /// /// The encoding to use. /// The number of cells that this segment occupies in the console. public int CellLength(Encoding encoding) { return Text.CellLength(encoding); } /// /// Returns a new segment without any trailing line endings. /// /// A new segment without any trailing line endings. public Segment StripLineEndings() { return new Segment(Text.TrimEnd('\n'), Appearance); } /// /// Splits the provided segments into lines. /// /// The segments to split. /// A collection of lines. public static List Split(IEnumerable segments) { if (segments is null) { throw new ArgumentNullException(nameof(segments)); } var lines = new List(); var line = new SegmentLine(); foreach (var segment in segments) { if (segment.Text.Contains("\n")) { if (segment.Text == "\n") { lines.Add(line); line = new SegmentLine(); continue; } var text = segment.Text; while (text != null) { var parts = text.SplitLines(); if (parts.Length > 0) { line.Add(new Segment(parts[0], segment.Appearance)); } if (parts.Length > 1) { lines.Add(line); line = new SegmentLine(); text = string.Concat(parts.Skip(1).Take(parts.Length - 1)); if (string.IsNullOrWhiteSpace(text)) { text = null; } } else { text = null; } } } else { line.Add(segment); } } if (line.Count > 0) { lines.Add(line); } return lines; } } }