1
0
mirror of https://github.com/oliverbooth/X10D synced 2024-11-09 23:25:43 +00:00

feat: add markdown formatting methods

This commit is contained in:
Oliver Booth 2023-08-27 03:37:01 +01:00
parent bd823ba818
commit 5d936b5385
Signed by: oliverbooth
GPG Key ID: B89D139977693FED
3 changed files with 329 additions and 0 deletions

View File

@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`. - X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`. - X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `string.ConcatIf`. - X10D: Added `string.ConcatIf`.
- X10D: Added `string.MDBold`, `string.MDCode`, `string.MDCodeBlock([string])`, `string.MDHeading(int)`,
`string.MDItalic`, `string.MDLink`, `string.MDStrikeOut`, and `string.MDUnderline` for Markdown formatting.
- X10D.Unity: Added `RaycastHit.GetComponent` and `RaycastHit.TryGetComponent`. - X10D.Unity: Added `RaycastHit.GetComponent` and `RaycastHit.TryGetComponent`.
- X10D.Unity: Added `DebugUtility.DrawFunction`, and `DebugUtility.DrawUnjoinedPolyhedron` on which it relies. - X10D.Unity: Added `DebugUtility.DrawFunction`, and `DebugUtility.DrawUnjoinedPolyhedron` on which it relies.

View File

@ -0,0 +1,122 @@
using NUnit.Framework;
using X10D.Text;
namespace X10D.Tests.Text;
[TestFixture]
internal class MarkdownTests
{
[Test]
public void MDBold_ShouldThrowArgumentNullException_GivenNull()
{
Assert.Throws<ArgumentNullException>(() => ((string)null!).MDBold());
}
[Test]
public void MDBold_ShouldReturnBoldText_GivenText()
{
Assert.That("Hello, world!".MDBold(), Is.EqualTo("**Hello, world!**"));
}
[Test]
public void MDCode_ShouldThrowArgumentNullException_GivenNull()
{
Assert.Throws<ArgumentNullException>(() => ((string)null!).MDCode());
}
[Test]
public void MDCode_ShouldReturnCodeText_GivenText()
{
Assert.That("Hello, world!".MDCode(), Is.EqualTo("`Hello, world!`"));
}
[Test]
public void MDCodeBlock_ShouldThrowArgumentNullException_GivenNull()
{
Assert.Throws<ArgumentNullException>(() => ((string)null!).MDCodeBlock());
}
[Test]
public void MDCodeBlock_ShouldReturnCodeBlockText_GivenText()
{
Assert.That("Hello, world!".MDCodeBlock(), Is.EqualTo($"```{Environment.NewLine}Hello, world!{Environment.NewLine}```"));
}
[Test]
public void MDCodeBlock_ShouldReturnCodeBlockText_GivenTextAndLanguage()
{
Assert.That("Hello, world!".MDCodeBlock("csharp"), Is.EqualTo($"```csharp{Environment.NewLine}Hello, world!{Environment.NewLine}```"));
}
[Test]
public void MDHeading_ShouldThrowArgumentNullException_GivenNull()
{
Assert.Throws<ArgumentNullException>(() => ((string)null!).MDHeading(1));
}
[Test]
public void MDHeading_ShouldThrowArgumentOutOfRangeException_GivenInvalidHeading()
{
Assert.Throws<ArgumentOutOfRangeException>(() => "Hello, world!".MDHeading(0));
Assert.Throws<ArgumentOutOfRangeException>(() => "Hello, world!".MDHeading(7));
}
[Test]
public void MDHeading_ShouldReturnHeadingText_GivenText()
{
Assert.That("Hello, world!".MDHeading(1), Is.EqualTo("# Hello, world!"));
Assert.That("Hello, world!".MDHeading(2), Is.EqualTo("## Hello, world!"));
Assert.That("Hello, world!".MDHeading(3), Is.EqualTo("### Hello, world!"));
Assert.That("Hello, world!".MDHeading(4), Is.EqualTo("#### Hello, world!"));
Assert.That("Hello, world!".MDHeading(5), Is.EqualTo("##### Hello, world!"));
Assert.That("Hello, world!".MDHeading(6), Is.EqualTo("###### Hello, world!"));
}
[Test]
public void MDItalic_ShouldThrowArgumentNullException_GivenNull()
{
Assert.Throws<ArgumentNullException>(() => ((string)null!).MDItalic());
}
[Test]
public void MDItalic_ShouldReturnItalicTextWithAsterisk_GivenText()
{
Assert.That("Hello, world!".MDItalic(), Is.EqualTo("*Hello, world!*"));
}
[Test]
public void MDItalic_ShouldReturnItalicTextWithAsterisk_GivenText_AndFalseUnderscoreFlag()
{
Assert.That("Hello, world!".MDItalic(false), Is.EqualTo("*Hello, world!*"));
}
[Test]
public void MDItalic_ShouldReturnItalicTextWithUnderscores_GivenText_AndTrueUnderscoreFlag()
{
Assert.That("Hello, world!".MDItalic(true), Is.EqualTo("_Hello, world!_"));
}
[Test]
public void MDStrikeOut_ShouldThrowArgumentNullException_GivenNull()
{
Assert.Throws<ArgumentNullException>(() => ((string)null!).MDStrikeOut());
}
[Test]
public void MDStrikeOut_ShouldReturnStrikeOutText_GivenText()
{
Assert.That("Hello, world!".MDStrikeOut(), Is.EqualTo("~~Hello, world!~~"));
}
[Test]
public void MDUnderline_ShouldThrowArgumentNullException_GivenNull()
{
Assert.Throws<ArgumentNullException>(() => ((string)null!).MDUnderline());
}
[Test]
public void MDUnderline_ShouldReturnUnderlineText_GivenText()
{
Assert.That("Hello, world!".MDUnderline(), Is.EqualTo("__Hello, world!__"));
}
}

View File

@ -0,0 +1,205 @@
namespace X10D.Text;
/// <summary>
/// Markdown-related extension methods for <see cref="string" />.
/// </summary>
public static class MarkdownExtensions
{
/// <summary>
/// Formats the specified text as bold, using Markdown.
/// </summary>
/// <param name="value">The value to surround with bold.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
public static string MDBold(this string value)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
return $"**{value}**";
}
/// <summary>
/// Formats the specified text as code, using Markdown.
/// </summary>
/// <param name="value">The value to surround with code.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
public static string MDCode(this string value)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
return $"`{value}`";
}
/// <summary>
/// Formats the specified text as a code block, using Markdown.
/// </summary>
/// <param name="value">The value to surround with code blocks.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
public static string MDCodeBlock(this string value)
{
return MDCodeBlock(value, string.Empty);
}
/// <summary>
/// Formats the specified text as a code block, using Markdown.
/// </summary>
/// <param name="value">The value to surround with code blocks.</param>
/// <param name="language">The language to use for syntax highlighting.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
public static string MDCodeBlock(this string value, string language)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
return $"```{language}{Environment.NewLine}{value}{Environment.NewLine}```";
}
/// <summary>
/// Formats the specified text as a heading, using Markdown.
/// </summary>
/// <param name="value">The value to surround with italics.</param>
/// <param name="level">The level of the heading.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="level" /> is less than 1 or greater than 6.</exception>
public static string MDHeading(this string value, int level)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
if (level is < 1 or > 6)
{
throw new ArgumentOutOfRangeException(nameof(level));
}
return $"{'#'.Repeat(level)} {value}";
}
/// <summary>
/// Formats the specified text as italics, using Markdown.
/// </summary>
/// <param name="value">The value to surround with italics.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
/// <remarks>
/// Markdown has two methods of italicizing text: <c>*</c> and <c>_</c>. This method uses asterisks by default. To
/// use underscores, use <see cref="MDItalic(string, bool)" /> and pass <see langword="true" /> as the second argument.
/// </remarks>
public static string MDItalic(this string value)
{
return MDItalic(value, false);
}
/// <summary>
/// Formats the specified text as italics, using Markdown.
/// </summary>
/// <param name="value">The value to surround with italics.</param>
/// <param name="useUnderscores">Whether to use underscores instead of asterisks for italicizing.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
public static string MDItalic(this string value, bool useUnderscores)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
return useUnderscores ? $"_{value}_" : $"*{value}*";
}
/// <summary>
/// Formats the specified text as a link, using Markdown.
/// </summary>
/// <param name="label">The label to use for the link.</param>
/// <param name="url">The URL to link to.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="url" /> is null.</exception>
public static string MDLink(this string? label, string url)
{
if (url is null)
{
throw new ArgumentNullException(nameof(url));
}
return string.IsNullOrWhiteSpace(label) ? url : $"[{label}]({url})";
}
/// <summary>
/// Formats the specified text as a link, using Markdown.
/// </summary>
/// <param name="label">The label to use for the link.</param>
/// <param name="url">The URL to link to.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="url" /> is null.</exception>
public static string MDLink(this string? label, Uri url)
{
if (url is null)
{
throw new ArgumentNullException(nameof(url));
}
return string.IsNullOrWhiteSpace(label) ? url.ToString() : $"[{label}]({url})";
}
/// <summary>
/// Formats the specified text as a link, using Markdown.
/// </summary>
/// <param name="url">The URL to link to.</param>
/// <param name="label">The label to use for the link.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="url" /> is null.</exception>
public static string MDLink(this Uri url, string? label)
{
if (url is null)
{
throw new ArgumentNullException(nameof(url));
}
return string.IsNullOrWhiteSpace(label) ? url.ToString() : $"[{label}]({url})";
}
/// <summary>
/// Formats the specified text as striked out, using Markdown.
/// </summary>
/// <param name="value">The value to surround with strikeout.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
public static string MDStrikeOut(this string value)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
return $"~~{value}~~";
}
/// <summary>
/// Formats the specified text as underlined, using Markdown.
/// </summary>
/// <param name="value">The value to surround with underline.</param>
/// <returns>The formatted text.</returns>
/// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
public static string MDUnderline(this string value)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
return $"__{value}__";
}
}