feature: Add Quote Formatting (#1348)
* Implement Quote Formatting Adds support for block quote text formatting. This feature is currently only implemented in the Canary client. This formatting adds a "> " to each new line from the input text. * add > char to character sanitization * change assumptions around whitespace strings * add blockquote (>>>) formatting + test
This commit is contained in:
committed by
Christopher F
parent
52565ed0de
commit
265da99619
@@ -1,10 +1,12 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
/// <summary> A helper class for formatting characters. </summary>
|
/// <summary> A helper class for formatting characters. </summary>
|
||||||
public static class Format
|
public static class Format
|
||||||
{
|
{
|
||||||
// Characters which need escaping
|
// Characters which need escaping
|
||||||
private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`", "|" };
|
private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`", "|", ">" };
|
||||||
|
|
||||||
/// <summary> Returns a markdown-formatted string with bold formatting. </summary>
|
/// <summary> Returns a markdown-formatted string with bold formatting. </summary>
|
||||||
public static string Bold(string text) => $"**{text}**";
|
public static string Bold(string text) => $"**{text}**";
|
||||||
@@ -37,5 +39,57 @@ namespace Discord
|
|||||||
text = text.Replace(unsafeChar, $"\\{unsafeChar}");
|
text = text.Replace(unsafeChar, $"\\{unsafeChar}");
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Formats a string as a quote.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The text to format.</param>
|
||||||
|
/// <returns>Gets the formatted quote text.</returns>
|
||||||
|
public static string Quote(string text)
|
||||||
|
{
|
||||||
|
// do not modify null or whitespace text
|
||||||
|
// whitespace does not get quoted properly
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
return text;
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
int startIndex = 0;
|
||||||
|
int newLineIndex;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
newLineIndex = text.IndexOf('\n', startIndex);
|
||||||
|
if (newLineIndex == -1)
|
||||||
|
{
|
||||||
|
// read the rest of the string
|
||||||
|
var str = text.Substring(startIndex);
|
||||||
|
result.Append($"> {str}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// read until the next newline
|
||||||
|
var str = text.Substring(startIndex, newLineIndex - startIndex);
|
||||||
|
result.Append($"> {str}\n");
|
||||||
|
}
|
||||||
|
startIndex = newLineIndex + 1;
|
||||||
|
}
|
||||||
|
while (newLineIndex != -1 && startIndex != text.Length);
|
||||||
|
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Formats a string as a block quote.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The text to format.</param>
|
||||||
|
/// <returns>Gets the formatted block quote text.</returns>
|
||||||
|
public static string BlockQuote(string text)
|
||||||
|
{
|
||||||
|
// do not modify null or whitespace
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
return text;
|
||||||
|
|
||||||
|
return $">>> {text}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Discord
|
|||||||
[InlineData(@"~text~", @"\~text\~")]
|
[InlineData(@"~text~", @"\~text\~")]
|
||||||
[InlineData(@"`text`", @"\`text\`")]
|
[InlineData(@"`text`", @"\`text\`")]
|
||||||
[InlineData(@"_text_", @"\_text\_")]
|
[InlineData(@"_text_", @"\_text\_")]
|
||||||
|
[InlineData(@"> text", @"\> text")]
|
||||||
public void Sanitize(string input, string expected)
|
public void Sanitize(string input, string expected)
|
||||||
{
|
{
|
||||||
Assert.Equal(expected, Format.Sanitize(input));
|
Assert.Equal(expected, Format.Sanitize(input));
|
||||||
@@ -28,5 +29,35 @@ namespace Discord
|
|||||||
Assert.Equal("```cs\ntest\n```", Format.Code("test", "cs"));
|
Assert.Equal("```cs\ntest\n```", Format.Code("test", "cs"));
|
||||||
Assert.Equal("```cs\nanother\none\n```", Format.Code("another\none", "cs"));
|
Assert.Equal("```cs\nanother\none\n```", Format.Code("another\none", "cs"));
|
||||||
}
|
}
|
||||||
|
[Fact]
|
||||||
|
public void QuoteNullString()
|
||||||
|
{
|
||||||
|
Assert.Null(Format.Quote(null));
|
||||||
|
}
|
||||||
|
[Theory]
|
||||||
|
[InlineData("", "")]
|
||||||
|
[InlineData("\n", "\n")]
|
||||||
|
[InlineData("foo\n\nbar", "> foo\n> \n> bar")]
|
||||||
|
[InlineData("input", "> input")] // single line
|
||||||
|
// should work with CR or CRLF
|
||||||
|
[InlineData("inb4\ngreentext", "> inb4\n> greentext")]
|
||||||
|
[InlineData("inb4\r\ngreentext", "> inb4\r\n> greentext")]
|
||||||
|
public void Quote(string input, string expected)
|
||||||
|
{
|
||||||
|
Assert.Equal(expected, Format.Quote(input));
|
||||||
|
}
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null, null)]
|
||||||
|
[InlineData("", "")]
|
||||||
|
[InlineData("\n", "\n")]
|
||||||
|
[InlineData("foo\n\nbar", ">>> foo\n\nbar")]
|
||||||
|
[InlineData("input", ">>> input")] // single line
|
||||||
|
// should work with CR or CRLF
|
||||||
|
[InlineData("inb4\ngreentext", ">>> inb4\ngreentext")]
|
||||||
|
[InlineData("inb4\r\ngreentext", ">>> inb4\r\ngreentext")]
|
||||||
|
public void BlockQuote(string input, string expected)
|
||||||
|
{
|
||||||
|
Assert.Equal(expected, Format.BlockQuote(input));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user