mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-16 00:42:51 +08:00
Add various exception improvements
This commit is contained in:
parent
39a8588dc3
commit
68e92f3365
BIN
docs/input/assets/images/custom_exception.png
Normal file
BIN
docs/input/assets/images/custom_exception.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 159 KiB |
@ -9,9 +9,9 @@ You can make exception a bit more readable by using the `WriteException` method.
|
||||
AnsiConsole.WriteException(ex);
|
||||
```
|
||||
|
||||
<img src="assets/images/exception.png" style="max-width: 100%; margin-bottom: 20px">
|
||||
|
||||
<img src="assets/images/exception.png" style="max-width: 100%;">
|
||||
|
||||
## Shortening parts
|
||||
|
||||
You can also shorten specific parts of the exception to make it even
|
||||
more readable, and make paths clickable hyperlinks. Whether or not
|
||||
@ -24,3 +24,29 @@ AnsiConsole.WriteException(ex,
|
||||
```
|
||||
|
||||
<img src="assets/images/compact_exception.png" style="max-width: 100%;">
|
||||
|
||||
## Customizing exception output
|
||||
|
||||
In addition to shorten specific part of the exception, you can
|
||||
also override the default styling.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.WriteException(ex, new ExceptionSettings
|
||||
{
|
||||
Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
|
||||
Style = new ExceptionStyle
|
||||
{
|
||||
Exception = Style.WithForeground(Color.Grey),
|
||||
Message = Style.WithForeground(Color.White),
|
||||
NonEmphasized = Style.WithForeground(Color.Cornsilk1),
|
||||
Parenthesis = Style.WithForeground(Color.Cornsilk1),
|
||||
Method = Style.WithForeground(Color.Red),
|
||||
ParameterName = Style.WithForeground(Color.Cornsilk1),
|
||||
ParameterType = Style.WithForeground(Color.Red),
|
||||
Path = Style.WithForeground(Color.Red),
|
||||
LineNumber = Style.WithForeground(Color.Cornsilk1),
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
<img src="assets/images/custom_exception.png" style="max-width: 100%;">
|
||||
|
@ -43,6 +43,12 @@ AnsiConsole.Markup("[[Hello]] "); // [Hello]
|
||||
AnsiConsole.Markup("[red][[World]][/]"); // [World]
|
||||
```
|
||||
|
||||
You can also use the `SafeMarkup` extension method.
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Markup("[red]{0}[/]", "Hello [World]".SafeMarkup());
|
||||
```
|
||||
|
||||
# Setting background color
|
||||
|
||||
You can set the background color in markup by prefixing the color with
|
||||
|
@ -14,11 +14,35 @@ namespace Exceptions
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Panel("[u]Default[/]").Expand());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Panel("[u]Compact[/]").Expand());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks);
|
||||
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(new Panel("[u]Custom colors[/]").Expand());
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.WriteException(ex, new ExceptionSettings
|
||||
{
|
||||
Format = ExceptionFormats.ShortenEverything | ExceptionFormats.ShowLinks,
|
||||
Style = new ExceptionStyle
|
||||
{
|
||||
Exception = Style.WithForeground(Color.Grey),
|
||||
Message = Style.WithForeground(Color.White),
|
||||
NonEmphasized = Style.WithForeground(Color.Cornsilk1),
|
||||
Parenthesis = Style.WithForeground(Color.Cornsilk1),
|
||||
Method = Style.WithForeground(Color.Red),
|
||||
ParameterName = Style.WithForeground(Color.Cornsilk1),
|
||||
ParameterType = Style.WithForeground(Color.Red),
|
||||
Path = Style.WithForeground(Color.Red),
|
||||
LineNumber = Style.WithForeground(Color.Cornsilk1),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,6 +228,39 @@ namespace Spectre.Console.Tests.Unit
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TheToMarkupMethod
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Default_Color()
|
||||
{
|
||||
// Given, When
|
||||
var result = Color.Default.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("default");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Known_Color()
|
||||
{
|
||||
// Given, When
|
||||
var result = Color.Red.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("red");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Custom_Color()
|
||||
{
|
||||
// Given, When
|
||||
var result = new Color(255, 1, 12).ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("#FF010C");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TheToStringMethod
|
||||
{
|
||||
[Fact]
|
||||
|
@ -317,5 +317,60 @@ namespace Spectre.Console.Tests.Unit
|
||||
result.ShouldBeFalse();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class TheToMarkupMethod
|
||||
{
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Foreground_Color()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(Color.Red);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("red");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Foreground_And_Background_Color()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(Color.Red, Color.Green);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("red on green");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Foreground_And_Background_Color_And_Decoration()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(Color.Red, Color.Green, Decoration.Bold | Decoration.Underline);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("bold underline red on green");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Expected_Markup_For_Style_With_Only_Background_Color()
|
||||
{
|
||||
// Given
|
||||
var style = new Style(background: Color.Green);
|
||||
|
||||
// When
|
||||
var result = style.ToMarkup();
|
||||
|
||||
// Then
|
||||
result.ShouldBe("default on green");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,5 +16,15 @@ namespace Spectre.Console
|
||||
{
|
||||
Console.WriteException(exception, format);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="settings">The exception settings.</param>
|
||||
public static void WriteException(Exception exception, ExceptionSettings settings)
|
||||
{
|
||||
Console.WriteException(exception, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -249,8 +249,13 @@ namespace Spectre.Console
|
||||
/// Converts the color to a markup string.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="string"/> representing the color as markup.</returns>
|
||||
public string ToMarkupString()
|
||||
public string ToMarkup()
|
||||
{
|
||||
if (IsDefault)
|
||||
{
|
||||
return "default";
|
||||
}
|
||||
|
||||
if (Number != null)
|
||||
{
|
||||
var name = ColorTable.GetName(Number.Value);
|
||||
|
27
src/Spectre.Console/ExceptionSettings.cs
Normal file
27
src/Spectre.Console/ExceptionSettings.cs
Normal file
@ -0,0 +1,27 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception settings.
|
||||
/// </summary>
|
||||
public sealed class ExceptionSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the exception format.
|
||||
/// </summary>
|
||||
public ExceptionFormats Format { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exception style.
|
||||
/// </summary>
|
||||
public ExceptionStyle Style { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExceptionSettings"/> class.
|
||||
/// </summary>
|
||||
public ExceptionSettings()
|
||||
{
|
||||
Format = ExceptionFormats.Default;
|
||||
Style = new ExceptionStyle();
|
||||
}
|
||||
}
|
||||
}
|
58
src/Spectre.Console/ExceptionStyle.cs
Normal file
58
src/Spectre.Console/ExceptionStyle.cs
Normal file
@ -0,0 +1,58 @@
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent an exception style.
|
||||
/// </summary>
|
||||
public sealed class ExceptionStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the message color.
|
||||
/// </summary>
|
||||
public Style Message { get; set; } = new Style(Color.Red, Color.Default, Decoration.Bold);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exception color.
|
||||
/// </summary>
|
||||
public Style Exception { get; set; } = new Style(Color.White);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the method color.
|
||||
/// </summary>
|
||||
public Style Method { get; set; } = new Style(Color.Yellow);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter type color.
|
||||
/// </summary>
|
||||
public Style ParameterType { get; set; } = new Style(Color.Blue);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter name color.
|
||||
/// </summary>
|
||||
public Style ParameterName { get; set; } = new Style(Color.Silver);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parenthesis color.
|
||||
/// </summary>
|
||||
public Style Parenthesis { get; set; } = new Style(Color.Silver);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path color.
|
||||
/// </summary>
|
||||
public Style Path { get; set; } = new Style(Color.Yellow, Color.Default, Decoration.Bold);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the line number color.
|
||||
/// </summary>
|
||||
public Style LineNumber { get; set; } = new Style(Color.Blue);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color for dimmed text such as "at" or "in".
|
||||
/// </summary>
|
||||
public Style Dimmed { get; set; } = new Style(Color.Grey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color for non emphasized items.
|
||||
/// </summary>
|
||||
public Style NonEmphasized { get; set; } = new Style(Color.Silver);
|
||||
}
|
||||
}
|
@ -17,5 +17,16 @@ namespace Spectre.Console
|
||||
{
|
||||
Render(console, exception.GetRenderable(format));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an exception to the console.
|
||||
/// </summary>
|
||||
/// <param name="console">The console.</param>
|
||||
/// <param name="exception">The exception to write to the console.</param>
|
||||
/// <param name="settings">The exception settings.</param>
|
||||
public static void WriteException(this IAnsiConsole console, Exception exception, ExceptionSettings settings)
|
||||
{
|
||||
Render(console, exception.GetRenderable(settings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,36 @@ namespace Spectre.Console
|
||||
/// <returns>A <see cref="IRenderable"/> representing the exception.</returns>
|
||||
public static IRenderable GetRenderable(this Exception exception, ExceptionFormats format = ExceptionFormats.Default)
|
||||
{
|
||||
return ExceptionFormatter.Format(exception, format);
|
||||
if (exception is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(exception));
|
||||
}
|
||||
|
||||
return GetRenderable(exception, new ExceptionSettings
|
||||
{
|
||||
Format = format,
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="IRenderable"/> representation of the exception.
|
||||
/// </summary>
|
||||
/// <param name="exception">The exception to format.</param>
|
||||
/// <param name="settings">The exception settings.</param>
|
||||
/// <returns>A <see cref="IRenderable"/> representing the exception.</returns>
|
||||
public static IRenderable GetRenderable(this Exception exception, ExceptionSettings settings)
|
||||
{
|
||||
if (exception is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(exception));
|
||||
}
|
||||
|
||||
if (settings is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
return ExceptionFormatter.Format(exception, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
{
|
||||
internal static class DecorationTable
|
||||
{
|
||||
private static readonly Dictionary<string, Decoration?> _lookup;
|
||||
private static readonly Dictionary<Decoration, string> _reverseLookup;
|
||||
|
||||
[SuppressMessage("Performance", "CA1810:Initialize reference type static fields inline")]
|
||||
static DecorationTable()
|
||||
@ -28,6 +30,21 @@ namespace Spectre.Console.Internal
|
||||
{ "strikethrough", Decoration.Strikethrough },
|
||||
{ "s", Decoration.Strikethrough },
|
||||
};
|
||||
|
||||
_reverseLookup = new Dictionary<Decoration, string>();
|
||||
foreach (var (name, decoration) in _lookup)
|
||||
{
|
||||
// Cannot happen, but the compiler thinks so...
|
||||
if (decoration == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_reverseLookup.ContainsKey(decoration.Value))
|
||||
{
|
||||
_reverseLookup[decoration.Value] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Decoration? GetDecoration(string name)
|
||||
@ -35,5 +52,23 @@ namespace Spectre.Console.Internal
|
||||
_lookup.TryGetValue(name, out var result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<string> GetMarkupNames(Decoration decoration)
|
||||
{
|
||||
var result = new List<string>();
|
||||
|
||||
Enum.GetValues(typeof(Decoration))
|
||||
.Cast<Decoration>()
|
||||
.Where(flag => (decoration & flag) != 0)
|
||||
.ForEach(flag =>
|
||||
{
|
||||
if (flag != Decoration.None && _reverseLookup.TryGetValue(flag, out var name))
|
||||
{
|
||||
result.Add(name);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,7 @@ namespace Spectre.Console
|
||||
{
|
||||
internal static class ExceptionFormatter
|
||||
{
|
||||
private static readonly Color _typeColor = Color.White;
|
||||
private static readonly Color _methodColor = Color.Yellow;
|
||||
private static readonly Color _parameterColor = Color.Blue;
|
||||
private static readonly Color _pathColor = Color.Yellow;
|
||||
private static readonly Color _dimmedColor = Color.Grey;
|
||||
|
||||
public static IRenderable Format(Exception exception, ExceptionFormats format)
|
||||
public static IRenderable Format(Exception exception, ExceptionSettings settings)
|
||||
{
|
||||
if (exception is null)
|
||||
{
|
||||
@ -27,10 +21,10 @@ namespace Spectre.Console
|
||||
return new Text(exception.ToString());
|
||||
}
|
||||
|
||||
return GetException(info, format);
|
||||
return GetException(info, settings);
|
||||
}
|
||||
|
||||
private static IRenderable GetException(ExceptionInfo info, ExceptionFormats format)
|
||||
private static IRenderable GetException(ExceptionInfo info, ExceptionSettings settings)
|
||||
{
|
||||
if (info is null)
|
||||
{
|
||||
@ -39,20 +33,20 @@ namespace Spectre.Console
|
||||
|
||||
return new Rows(new IRenderable[]
|
||||
{
|
||||
GetMessage(info, format),
|
||||
GetStackFrames(info, format),
|
||||
GetMessage(info, settings),
|
||||
GetStackFrames(info, settings),
|
||||
}).Expand();
|
||||
}
|
||||
|
||||
private static Markup GetMessage(ExceptionInfo ex, ExceptionFormats format)
|
||||
private static Markup GetMessage(ExceptionInfo ex, ExceptionSettings settings)
|
||||
{
|
||||
var shortenTypes = (format & ExceptionFormats.ShortenTypes) != 0;
|
||||
var type = Emphasize(ex.Type, new[] { '.' }, _typeColor.ToMarkupString(), shortenTypes);
|
||||
var message = $"[b red]{ex.Message.SafeMarkup()}[/]";
|
||||
var shortenTypes = (settings.Format & ExceptionFormats.ShortenTypes) != 0;
|
||||
var type = Emphasize(ex.Type, new[] { '.' }, settings.Style.Exception, shortenTypes, settings);
|
||||
var message = $"[{settings.Style.Message.ToMarkup()}]{ex.Message.SafeMarkup()}[/]";
|
||||
return new Markup(string.Concat(type, ": ", message));
|
||||
}
|
||||
|
||||
private static Grid GetStackFrames(ExceptionInfo ex, ExceptionFormats format)
|
||||
private static Grid GetStackFrames(ExceptionInfo ex, ExceptionSettings settings)
|
||||
{
|
||||
var grid = new Grid();
|
||||
grid.AddColumn(new GridColumn().PadLeft(2).PadRight(0).NoWrap());
|
||||
@ -63,7 +57,7 @@ namespace Spectre.Console
|
||||
{
|
||||
grid.AddRow(
|
||||
Text.Empty,
|
||||
GetException(ex.Inner, format));
|
||||
GetException(ex.Inner, settings));
|
||||
}
|
||||
|
||||
// Stack frames
|
||||
@ -72,47 +66,57 @@ namespace Spectre.Console
|
||||
var builder = new StringBuilder();
|
||||
|
||||
// Method
|
||||
var shortenMethods = (format & ExceptionFormats.ShortenMethods) != 0;
|
||||
builder.Append(Emphasize(frame.Method, new[] { '.' }, _methodColor.ToMarkupString(), shortenMethods));
|
||||
builder.Append('(');
|
||||
builder.Append(string.Join(", ", frame.Parameters.Select(x => $"[{_parameterColor.ToMarkupString()}]{x.Type.SafeMarkup()}[/] {x.Name}")));
|
||||
builder.Append(')');
|
||||
var shortenMethods = (settings.Format & ExceptionFormats.ShortenMethods) != 0;
|
||||
builder.Append(Emphasize(frame.Method, new[] { '.' }, settings.Style.Method, shortenMethods, settings));
|
||||
builder.Append('[').Append(settings.Style.Parenthesis.ToMarkup()).Append(']').Append('(').Append("[/]");
|
||||
AppendParameters(builder, frame, settings);
|
||||
builder.Append('[').Append(settings.Style.Parenthesis.ToMarkup()).Append(']').Append(')').Append("[/]");
|
||||
|
||||
if (frame.Path != null)
|
||||
{
|
||||
builder.Append(" [").Append(_dimmedColor.ToMarkupString()).Append("]in[/] ");
|
||||
builder.Append(" [").Append(settings.Style.Dimmed.ToMarkup()).Append("]in[/] ");
|
||||
|
||||
// Path
|
||||
AppendPath(builder, frame, format);
|
||||
AppendPath(builder, frame, settings);
|
||||
|
||||
// Line number
|
||||
if (frame.LineNumber != null)
|
||||
{
|
||||
builder.Append(':');
|
||||
builder.Append('[').Append(_parameterColor.ToMarkupString()).Append(']').Append(frame.LineNumber).Append("[/]");
|
||||
builder.Append('[').Append(settings.Style.Dimmed.ToMarkup()).Append("]:[/]");
|
||||
builder.Append('[').Append(settings.Style.LineNumber.ToMarkup()).Append(']').Append(frame.LineNumber).Append("[/]");
|
||||
}
|
||||
}
|
||||
|
||||
grid.AddRow($"[{_dimmedColor.ToMarkupString()}]at[/]", builder.ToString());
|
||||
grid.AddRow(
|
||||
$"[{settings.Style.Dimmed.ToMarkup()}]at[/]",
|
||||
builder.ToString());
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
private static void AppendPath(StringBuilder builder, StackFrameInfo frame, ExceptionFormats format)
|
||||
private static void AppendParameters(StringBuilder builder, StackFrameInfo frame, ExceptionSettings settings)
|
||||
{
|
||||
var typeColor = settings.Style.ParameterType.ToMarkup();
|
||||
var nameColor = settings.Style.ParameterName.ToMarkup();
|
||||
var parameters = frame.Parameters.Select(x => $"[{typeColor}]{x.Type.SafeMarkup()}[/] [{nameColor}]{x.Name}[/]");
|
||||
builder.Append(string.Join(", ", parameters));
|
||||
}
|
||||
|
||||
private static void AppendPath(StringBuilder builder, StackFrameInfo frame, ExceptionSettings settings)
|
||||
{
|
||||
if (frame?.Path is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void RenderLink()
|
||||
void AppendPath()
|
||||
{
|
||||
var shortenPaths = (format & ExceptionFormats.ShortenPaths) != 0;
|
||||
builder.Append(Emphasize(frame.Path, new[] { '/', '\\' }, $"b {_pathColor.ToMarkupString()}", shortenPaths));
|
||||
var shortenPaths = (settings.Format & ExceptionFormats.ShortenPaths) != 0;
|
||||
builder.Append(Emphasize(frame.Path, new[] { '/', '\\' }, settings.Style.Path, shortenPaths, settings));
|
||||
}
|
||||
|
||||
if ((format & ExceptionFormats.ShowLinks) != 0)
|
||||
if ((settings.Format & ExceptionFormats.ShowLinks) != 0)
|
||||
{
|
||||
var hasLink = frame.TryGetUri(out var uri);
|
||||
if (hasLink && uri != null)
|
||||
@ -120,7 +124,7 @@ namespace Spectre.Console
|
||||
builder.Append("[link=").Append(uri.AbsoluteUri).Append(']');
|
||||
}
|
||||
|
||||
RenderLink();
|
||||
AppendPath();
|
||||
|
||||
if (hasLink && uri != null)
|
||||
{
|
||||
@ -129,11 +133,11 @@ namespace Spectre.Console
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderLink();
|
||||
AppendPath();
|
||||
}
|
||||
}
|
||||
|
||||
private static string Emphasize(string input, char[] separators, string color, bool compact)
|
||||
private static string Emphasize(string input, char[] separators, Style color, bool compact, ExceptionSettings settings)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
@ -143,10 +147,12 @@ namespace Spectre.Console
|
||||
{
|
||||
if (!compact)
|
||||
{
|
||||
builder.Append("[silver]").Append(type, 0, index + 1).Append("[/]");
|
||||
builder.Append('[').Append(settings.Style.NonEmphasized.ToMarkup()).Append(']')
|
||||
.Append(type, 0, index + 1).Append("[/]");
|
||||
}
|
||||
|
||||
builder.Append('[').Append(color).Append(']').Append(type, index + 1, type.Length - index - 1).Append("[/]");
|
||||
builder.Append('[').Append(color.ToMarkup()).Append(']')
|
||||
.Append(type, index + 1, type.Length - index - 1).Append("[/]");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
{
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple, out T1 key, out T2 value)
|
||||
{
|
||||
key = tuple.Key;
|
||||
value = tuple.Value;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console
|
||||
@ -25,7 +27,7 @@ namespace Spectre.Console
|
||||
public Decoration Decoration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the link.
|
||||
/// Gets the link associated with the style.
|
||||
/// </summary>
|
||||
public string? Link { get; }
|
||||
|
||||
@ -191,6 +193,41 @@ namespace Spectre.Console
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the markup representation of this style.
|
||||
/// </summary>
|
||||
/// <returns>The markup representation of this style.</returns>
|
||||
public string ToMarkup()
|
||||
{
|
||||
var builder = new List<string>();
|
||||
|
||||
if (Decoration != Decoration.None)
|
||||
{
|
||||
var result = DecorationTable.GetMarkupNames(Decoration);
|
||||
if (result.Count != 0)
|
||||
{
|
||||
builder.AddRange(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (Foreground != Color.Default)
|
||||
{
|
||||
builder.Add(Foreground.ToMarkup());
|
||||
}
|
||||
|
||||
if (Background != Color.Default)
|
||||
{
|
||||
if (builder.Count == 0)
|
||||
{
|
||||
builder.Add("default");
|
||||
}
|
||||
|
||||
builder.Add("on " + Background.ToMarkup());
|
||||
}
|
||||
|
||||
return string.Join(" ", builder);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user