コード例 #1
0
 /// <summary>
 /// Transform the given string into a new one, preserving color.
 /// </summary>
 /// <param name="s">The input string.</param>
 /// <param name="func">The function to apply.</param>
 /// <returns>The generated string.</returns>
 /// <exception cref="ArgumentNullException">Thrown when <paramref name="func"/>
 /// is null.</exception>
 public static ColoredString Transform(this ColoredString s, Func <string, string> func)
 {
     if (func == null)
     {
         throw new ArgumentNullException(nameof(func));
     }
     return(new ColoredString(func(s.Content), s.ForegroundColor, s.BackgroundColor));
 }
コード例 #2
0
 /// <summary>
 /// Take the color of the given string to produce a new one, but with the given
 /// content.
 /// </summary>
 /// <param name="s">The input string.</param>
 /// <param name="newContent">The new content to use.</param>
 /// <returns>The generated string.</returns>
 /// <exception cref="ArgumentNullException">Thrown when <paramref name="newContent"/>
 /// is null.</exception>
 public static ColoredString WithContent(this ColoredString s, string newContent)
 {
     if (newContent == null)
     {
         throw new ArgumentNullException(nameof(newContent));
     }
     return(s.Transform(_ => newContent));
 }
コード例 #3
0
 /// <summary>
 /// Returns a new string containing a substring of the given string.
 /// </summary>
 /// <param name="s">The string.</param>
 /// <param name="startIndex">The 0-based index to start from.</param>
 /// <param name="length">The length of the substring, expressed as
 /// a count of characters.</param>
 /// <returns>The new string.</returns>
 public static ColoredString Substring(this ColoredString s, int startIndex, int length) =>
 s.Transform(content => content.Substring(startIndex, length));
コード例 #4
0
 /// <summary>
 /// Wrap the provided text at the given width, indenting it with the
 /// given indentation width.
 /// </summary>
 /// <param name="text">Text to wrap.</param>
 /// <param name="width">Maximum width of the text, in number of
 /// characters.</param>
 /// <param name="blockIndent">The number of characters to block-indent
 /// all lines. Use 0 to indicate no block indentation should occur.</param>
 /// <param name="hangingIndent">The number of characters to hanging-indent
 /// the text; all lines after the first line are affected, and the first
 /// line is left unmodified.  Use 0 to indicate no hanging indentation
 /// should occur.</param>
 /// <returns>The wrapped text.</returns>
 public static ColoredString Wrap(this ColoredString text, int width, int blockIndent = 0, int hangingIndent = 0) =>
 text.Transform(content => Wrap(content, width, blockIndent, hangingIndent));
コード例 #5
0
 /// <summary>
 /// Simple constructor.
 /// </summary>
 /// <param name="value">String content.</param>
 public ColoredMultistring(ColoredString value)
 {
     Content = new[] { value };
 }
コード例 #6
0
 /// <summary>
 /// Append a colored string followed by a newline.
 /// </summary>
 /// <param name="value">The colored string to append.</param>
 public void AppendLine(ColoredString value)
 {
     Append(value);
     Append(value.Transform(content => Environment.NewLine));
 }
コード例 #7
0
 /// <summary>
 /// Append a colored string.
 /// </summary>
 /// <param name="value">The colored string to append.</param>
 public void Append(ColoredString value) => Insert(Length, value);
コード例 #8
0
        /// <summary>
        /// Inserts the given string at the specified index.
        /// </summary>
        /// <param name="index">0-based index.</param>
        /// <param name="s">The string to insert.</param>
        public void Insert(int index, ColoredString s)
        {
            if (index < 0 || index > Length)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            // Optimization: don't bother if string is empty.
            if (s.IsEmpty())
            {
                return;
            }

            //
            // At this point, we're guaranteed it's either before or in
            // the middle of the existing contents.
            //

            var           pieceIndex = 0;
            var           offset     = 0;
            ColoredString?lastPiece  = null;

            while (pieceIndex < _pieces.Count)
            {
                var piece = _pieces[pieceIndex];
                Debug.Assert(!piece.IsEmpty());

                // Case 1: insertion point is just before this piece.
                if (index == offset)
                {
                    if (s.IsSameColorAs(piece))
                    {
                        _pieces.RemoveAt(pieceIndex);
                        _pieces.Insert(pieceIndex,
                                       piece.Transform(content => s.Content + content));
                    }
                    else
                    {
                        _pieces.Insert(pieceIndex, s);
                    }

                    _totalLength += s.Length;
                    return;
                }

                // Case 2: insertion point is in middle of this piece.
                else if (index < offset + piece.Length)
                {
                    _pieces.RemoveAt(pieceIndex);

                    if (s.IsSameColorAs(piece))
                    {
                        _pieces.Insert(pieceIndex, piece.Transform(content =>
                                                                   content.Substring(0, index - offset) +
                                                                   s.Content +
                                                                   content.Substring(index - offset)));
                    }
                    else
                    {
                        _pieces.Insert(pieceIndex, piece.Substring(0, index - offset));
                        _pieces.Insert(pieceIndex + 1, s);
                        _pieces.Insert(pieceIndex + 2, piece.Substring(index - offset));
                    }

                    _totalLength += s.Length;
                    return;
                }

                // Case 3: insertion point is just after this piece.
                // Only insert during this loop iteration if new piece
                // can be merged with this one.  We'll otherwise get it
                // the next time around.
                else if (index == offset + piece.Length)
                {
                    if (s.IsSameColorAs(piece))
                    {
                        _pieces.RemoveAt(pieceIndex);
                        _pieces.Insert(pieceIndex,
                                       piece.Transform(content => content + s.Content));

                        _totalLength += s.Length;
                        return;
                    }
                }

                offset   += piece.Length;
                lastPiece = piece;
                ++pieceIndex;
            }

            // If we're still here, then it goes at the end.
            Debug.Assert(index == Length);

            // Append.
            _pieces.Add(s);
            _totalLength += s.Length;
        }