Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
StringDecorated.cs190 linesDownload Raw Back to common
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#nullable enable5 6using System.Collections.Generic;7using System.Text.RegularExpressions;8 9namespace System.Management.Automation.Internal10{11    /// <summary>12    /// Extensions to String type to calculate and render decorated content.13    /// </summary>14    public class StringDecorated15    {16        private readonly bool _isDecorated;17        private readonly string _text;18        private string? _plaintextcontent;19 20        private string PlainText21        {22            get23            {24                _plaintextcontent ??= ValueStringDecorated.AnsiRegex.Replace(_text, string.Empty);25 26                return _plaintextcontent;27            }28        }29 30        /// <summary>31        /// Initializes a new instance of the <see cref="StringDecorated"/> class.32        /// </summary>33        /// <param name="text">The input string.</param>34        public StringDecorated(string text)35        {36            _text = text;37            _isDecorated = text.Contains(ValueStringDecorated.ESC);38        }39 40        /// <summary>41        /// Gets a value indicating whether the string contains decoration.42        /// </summary>43        /// <returns>Boolean if the string contains decoration.</returns>44        public bool IsDecorated => _isDecorated;45 46        /// <summary>47        /// Gets the length of content sans escape sequences.48        /// </summary>49        /// <returns>Length of content sans escape sequences.</returns>50        public int ContentLength => PlainText.Length;51 52        /// <summary>53        /// Render the decorarted string using automatic output rendering.54        /// </summary>55        /// <returns>Rendered string based on automatic output rendering.</returns>56        public override string ToString() => ToString(57            PSStyle.Instance.OutputRendering == OutputRendering.PlainText58                ? OutputRendering.PlainText59                : OutputRendering.Ansi);60 61        /// <summary>62        /// Return string representation of content depending on output rendering mode.63        /// </summary>64        /// <param name="outputRendering">Specify how to render the text content.</param>65        /// <returns>Rendered string based on outputRendering.</returns>66        public string ToString(OutputRendering outputRendering)67        {68            if (outputRendering == OutputRendering.Host)69            {70                throw new ArgumentException(StringDecoratedStrings.RequireExplicitRendering);71            }72 73            if (!_isDecorated)74            {75                return _text;76            }77 78            return outputRendering == OutputRendering.PlainText ? PlainText : _text;79        }80    }81 82    internal struct ValueStringDecorated83    {84        internal const char ESC = '\x1b';85        private readonly bool _isDecorated;86        private readonly string _text;87        private string? _plaintextcontent;88        private Dictionary<int, int>? _vtRanges;89 90        private string PlainText91        {92            get93            {94                _plaintextcontent ??= AnsiRegex.Replace(_text, string.Empty);95 96                return _plaintextcontent;97            }98        }99 100        // graphics/color mode ESC[1;2;...m101        private const string GraphicsRegex = @"(\x1b\[\d*(;\d+)*m)";102 103        // CSI escape sequences104        private const string CsiRegex = @"(\x1b\[\?\d+[hl])";105 106        // Hyperlink escape sequences. Note: '.*?' makes '.*' do non-greedy match.107        private const string HyperlinkRegex = @"(\x1b\]8;;.*?\x1b\\)";108 109        // replace regex with .NET 6 API once available110        internal static readonly Regex AnsiRegex = new Regex($"{GraphicsRegex}|{CsiRegex}|{HyperlinkRegex}", RegexOptions.Compiled);111 112        /// <summary>113        /// Get the ranges of all escape sequences in the text.114        /// </summary>115        /// <returns>116        /// A dictionary with the key being the starting index of an escape sequence,117        /// and the value being the length of the escape sequence.118        /// </returns>119        internal Dictionary<int, int>? EscapeSequenceRanges120        {121            get122            {123                if (_isDecorated && _vtRanges is null)124                {125                    _vtRanges = new Dictionary<int, int>();126                    foreach (Match match in AnsiRegex.Matches(_text))127                    {128                        _vtRanges.Add(match.Index, match.Length);129                    }130                }131 132                return _vtRanges;133            }134        }135 136        /// <summary>137        /// Initializes a new instance of the <see cref="ValueStringDecorated"/> struct.138        /// </summary>139        /// <param name="text">The input string.</param>140        public ValueStringDecorated(string text)141        {142            _text = text;143            _isDecorated = text.Contains(ESC);144            _plaintextcontent = _isDecorated ? null : text;145            _vtRanges = null;146        }147 148        /// <summary>149        /// Gets a value indicating whether the string contains decoration.150        /// </summary>151        /// <returns>Boolean if the string contains decoration.</returns>152        public bool IsDecorated => _isDecorated;153 154        /// <summary>155        /// Gets the length of content sans escape sequences.156        /// </summary>157        /// <returns>Length of content sans escape sequences.</returns>158        public int ContentLength => PlainText.Length;159 160        /// <summary>161        /// Render the decorarted string using automatic output rendering.162        /// </summary>163        /// <returns>Rendered string based on automatic output rendering.</returns>164        public override string ToString() => ToString(165            PSStyle.Instance.OutputRendering == OutputRendering.PlainText166                ? OutputRendering.PlainText167                : OutputRendering.Ansi);168 169        /// <summary>170        /// Return string representation of content depending on output rendering mode.171        /// </summary>172        /// <param name="outputRendering">Specify how to render the text content.</param>173        /// <returns>Rendered string based on outputRendering.</returns>174        public string ToString(OutputRendering outputRendering)175        {176            if (outputRendering == OutputRendering.Host)177            {178                throw new ArgumentException(StringDecoratedStrings.RequireExplicitRendering);179            }180 181            if (!_isDecorated)182            {183                return _text;184            }185 186            return outputRendering == OutputRendering.PlainText ? PlainText : _text;187        }188    }189}190