Files
spectre.console/src/Spectre.Console/Widgets/Markup.cs
Phil Scott 1d8154f9b0 Introduce MarkupInterpolated and MarkupLineInterpolated extensions (#761)
* Introduce MarkupInterpolated and MarkupLineInterpolated extensions

These new methods enable easily writing markup with a nice and intuitive syntax without having to worry about escaping the markup.

```csharp
string input = args[0];
string output = Process(input);
AnsiConsole.MarkupLineInterpolated($"[blue]{input}[/] -> [green]{output}[/]");

```

The `Interpolated` suffix was inspired by the Entity Framework Core [FromSqlInterpolated][1] method.

[1]: https://docs.microsoft.com/en-us/ef/core/querying/raw-sql#passing-parameters

* Fixing whitespace to match file scoped namespaces

* Adding FromInterpolated helper to Markup widget

Allows automatic handling of interpolated strings to be used on the Markup widget. This would be helpful for people working with Tables and the Tree control who would not be using the MarkupInterpolated methods.

* Documentation for markup interpolated methods.

Co-authored-by: Cédric Luthi <cedric.luthi@gmail.com>
2022-03-22 22:34:25 +01:00

115 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace Spectre.Console;
/// <summary>
/// A renderable piece of markup text.
/// </summary>
[SuppressMessage("Naming", "CA1724:Type names should not match namespaces")]
public sealed class Markup : Renderable, IAlignable, IOverflowable
{
private readonly Paragraph _paragraph;
/// <inheritdoc/>
public Justify? Alignment
{
get => _paragraph.Alignment;
set => _paragraph.Alignment = value;
}
/// <inheritdoc/>
public Overflow? Overflow
{
get => _paragraph.Overflow;
set => _paragraph.Overflow = value;
}
/// <summary>
/// Gets the character count.
/// </summary>
public int Length => _paragraph.Length;
/// <summary>
/// Gets the number of lines.
/// </summary>
public int Lines => _paragraph.Lines;
/// <summary>
/// Initializes a new instance of the <see cref="Markup"/> class.
/// </summary>
/// <param name="text">The markup text.</param>
/// <param name="style">The style of the text.</param>
public Markup(string text, Style? style = null)
{
_paragraph = MarkupParser.Parse(text, style);
}
/// <inheritdoc/>
protected override Measurement Measure(RenderContext context, int maxWidth)
{
return ((IRenderable)_paragraph).Measure(context, maxWidth);
}
/// <inheritdoc/>
protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
{
return ((IRenderable)_paragraph).Render(context, maxWidth);
}
/// <summary>
/// Returns a new instance of a Markup widget from an interpolated string.
/// </summary>
/// <param name="value">The interpolated string value to write.</param>
/// <param name="style">The style of the text.</param>
/// <returns>A new markup instance.</returns>
public static Markup FromInterpolated(FormattableString value, Style? style = null)
{
return FromInterpolated(CultureInfo.CurrentCulture, value, style);
}
/// <summary>
/// Returns a new instance of a Markup widget from an interpolated string.
/// </summary>
/// <param name="provider">The format provider to use.</param>
/// <param name="value">The interpolated string value to write.</param>
/// <param name="style">The style of the text.</param>
/// <returns>A new markup instance.</returns>
public static Markup FromInterpolated(IFormatProvider provider, FormattableString value, Style? style = null)
{
return new Markup(EscapeInterpolated(provider, value), style);
}
/// <summary>
/// Escapes text so that it wont be interpreted as markup.
/// </summary>
/// <param name="text">The text to escape.</param>
/// <returns>A string that is safe to use in markup.</returns>
public static string Escape(string text)
{
if (text is null)
{
throw new ArgumentNullException(nameof(text));
}
return text.EscapeMarkup();
}
/// <summary>
/// Removes markup from the specified string.
/// </summary>
/// <param name="text">The text to remove markup from.</param>
/// <returns>A string that does not have any markup.</returns>
public static string Remove(string text)
{
if (text is null)
{
throw new ArgumentNullException(nameof(text));
}
return text.RemoveMarkup();
}
internal static string EscapeInterpolated(IFormatProvider provider, FormattableString value)
{
object?[] args = value.GetArguments().Select(arg => arg is string s ? s.EscapeMarkup() : arg).ToArray();
return string.Format(provider, value.Format, args);
}
}