mirror of
https://github.com/xoofx/markdig.git
synced 2026-02-10 14:00:05 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e3416f8b7 | ||
|
|
012a57d361 | ||
|
|
053a18c684 | ||
|
|
13265453ac | ||
|
|
8ea0783834 | ||
|
|
3d29430337 | ||
|
|
81bc58c6c9 | ||
|
|
bfe3800130 | ||
|
|
b7cb169fd3 | ||
|
|
512b28256a | ||
|
|
cd5d11eeff | ||
|
|
a9118774a8 |
@@ -36,6 +36,16 @@ public class TestMediaLinks
|
||||
Assert.AreEqual(html, expected);
|
||||
}
|
||||
|
||||
[TestCase("",
|
||||
"<p><video width=\"500\" height=\"281\" controls=\"\"><source type=\"video/mp4\" src=\"./video.mp4\"></source></video></p>\n")]
|
||||
[TestCase("",
|
||||
"<p><audio width=\"500\" controls=\"\"><source type=\"audio/mpeg\" src=\"./audio.mp3\"></source></audio></p>\n")]
|
||||
public void TestBuiltInHostsWithRelativePaths(string markdown, string expected)
|
||||
{
|
||||
string html = Markdown.ToHtml(markdown, GetPipeline());
|
||||
Assert.AreEqual(html, expected);
|
||||
}
|
||||
|
||||
private class TestHostProvider : IHostProvider
|
||||
{
|
||||
public string Class { get; } = "regex";
|
||||
|
||||
@@ -180,4 +180,39 @@ public class TestStringSliceList
|
||||
Assert.AreEqual('\0', iterator.CurrentChar); iterator.SkipChar();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStringLineGroupCharIteratorAtCapacity()
|
||||
{
|
||||
string str = "ABCDEFGHI";
|
||||
var text = new StringLineGroup(1)
|
||||
{
|
||||
// Will store the following line at capacity
|
||||
new StringSlice(str, NewLine.CarriageReturnLineFeed) { Start = 0, End = 2 },
|
||||
};
|
||||
|
||||
var iterator = text.ToCharIterator();
|
||||
var chars = ToString(iterator);
|
||||
TextAssert.AreEqual("ABC\r\n", chars.ToString());
|
||||
TextAssert.AreEqual("ABC", text.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStringLineGroupCharIteratorForcingIncreaseCapacity()
|
||||
{
|
||||
string str = "ABCDEFGHI";
|
||||
var text = new StringLineGroup(1)
|
||||
{
|
||||
// Will store the following line at capacity
|
||||
new StringSlice(str, NewLine.CarriageReturnLineFeed) { Start = 0, End = 2 },
|
||||
|
||||
// Will force increase capacity to 2 and store the line at capacity
|
||||
new StringSlice(str, NewLine.CarriageReturnLineFeed) { Start = 3, End = 3 },
|
||||
};
|
||||
|
||||
var iterator = text.ToCharIterator();
|
||||
var chars = ToString(iterator);
|
||||
TextAssert.AreEqual("ABC\r\nD\r\n", chars.ToString());
|
||||
TextAssert.AreEqual("ABC\r\nD", text.ToString());
|
||||
}
|
||||
}
|
||||
@@ -83,4 +83,28 @@ public class TestYamlFrontMatterExtension
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("---\nkey1: value1\nkey2: value2\n---\n\n# Content\n")]
|
||||
[TestCase("---\nkey1: value1\nkey2: value2\nkey3: value3\nkey4: value4\nkey5: value5\nkey6: value6\nkey7: value7\nkey8: value8\n---\n\n# Content\n")]
|
||||
public void FrontMatterBlockLinesCharIterator(string value)
|
||||
{
|
||||
var builder = new MarkdownPipelineBuilder();
|
||||
builder.Extensions.Add(new YamlFrontMatterExtension());
|
||||
var markdownDocument = Markdown.Parse(value, builder.Build());
|
||||
|
||||
var yamlBlocks = markdownDocument.Descendants<YamlFrontMatterBlock>();
|
||||
Assert.True(yamlBlocks.Any());
|
||||
|
||||
foreach (var yamlBlock in yamlBlocks)
|
||||
{
|
||||
var iterator = yamlBlock.Lines.ToCharIterator();
|
||||
while(iterator.CurrentChar != '\0')
|
||||
{
|
||||
iterator.NextChar();
|
||||
}
|
||||
}
|
||||
|
||||
Assert.Pass("No exception parsing and iterating through YAML front matter block lines");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,27 +50,32 @@ public class MediaLinkExtension : IMarkdownExtension
|
||||
return false;
|
||||
}
|
||||
|
||||
var url = linkInline.Url;
|
||||
bool isSchemaRelative = false;
|
||||
// Only process absolute Uri
|
||||
if (!Uri.TryCreate(linkInline.Url, UriKind.RelativeOrAbsolute, out Uri? uri) || !uri.IsAbsoluteUri)
|
||||
|
||||
// force // schema to an absolute url
|
||||
if (url.StartsWith("//", StringComparison.Ordinal))
|
||||
{
|
||||
// see https://tools.ietf.org/html/rfc3986#section-4.2
|
||||
// since relative uri doesn't support many properties, "http" is used as a placeholder here.
|
||||
if (linkInline.Url.StartsWith("//", StringComparison.Ordinal) && Uri.TryCreate("http:" + linkInline.Url, UriKind.Absolute, out uri))
|
||||
url = "https:" + url;
|
||||
isSchemaRelative = true;
|
||||
}
|
||||
|
||||
// Make sure we have a valid absolute/relative url
|
||||
if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out Uri? uri)) // || !uri.IsAbsoluteUri)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// iFrame has to be absolute path
|
||||
if (uri.IsAbsoluteUri)
|
||||
{
|
||||
if (TryRenderIframeFromKnownProviders(uri, isSchemaRelative, renderer, linkInline))
|
||||
{
|
||||
isSchemaRelative = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (TryRenderIframeFromKnownProviders(uri, isSchemaRelative, renderer, linkInline))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// audio/video has can have relative path
|
||||
if (TryGuessAudioVideoFile(uri, isSchemaRelative, renderer, linkInline))
|
||||
{
|
||||
return true;
|
||||
@@ -93,7 +98,10 @@ public class MediaLinkExtension : IMarkdownExtension
|
||||
|
||||
private bool TryGuessAudioVideoFile(Uri uri, bool isSchemaRelative, HtmlRenderer renderer, LinkInline linkInline)
|
||||
{
|
||||
var path = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped);
|
||||
string path = uri.IsAbsoluteUri
|
||||
? uri.GetComponents(UriComponents.Path, UriFormat.Unescaped)
|
||||
: uri.ToString();
|
||||
|
||||
// Otherwise try to detect if we have an audio/video from the file extension
|
||||
var lastDot = path.LastIndexOf('.');
|
||||
if (lastDot >= 0 &&
|
||||
|
||||
@@ -334,9 +334,12 @@ public struct StringLineGroup : IEnumerable
|
||||
goto Return;
|
||||
|
||||
MoveToNewLine:
|
||||
SliceIndex++;
|
||||
_offset = -1;
|
||||
_currentSlice = _lines.Lines[SliceIndex];
|
||||
if (SliceIndex < _lines.Lines.Length - 1)
|
||||
{
|
||||
SliceIndex++;
|
||||
_offset = -1;
|
||||
_currentSlice = _lines.Lines[SliceIndex];
|
||||
}
|
||||
|
||||
Return:
|
||||
return CurrentChar;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Markdig;
|
||||
/// <summary>
|
||||
/// Provides methods for parsing a Markdown string to a syntax tree and converting it to other formats.
|
||||
/// </summary>
|
||||
public static partial class Markdown
|
||||
public static class Markdown
|
||||
{
|
||||
public static string Version
|
||||
{
|
||||
@@ -268,7 +268,7 @@ public static partial class Markdown
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Markdown string to HTML.
|
||||
/// Converts a Markdown string to Plain text by using a <see cref="StringWriter"/> .
|
||||
/// </summary>
|
||||
/// <param name="markdown">A Markdown text.</param>
|
||||
/// <param name="pipeline">The pipeline used for the conversion.</param>
|
||||
|
||||
@@ -17,7 +17,7 @@ internal sealed class NotNullWhenAttribute : Attribute
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
|
||||
public sealed class AllowNullAttribute : Attribute { }
|
||||
internal sealed class AllowNullAttribute : Attribute { }
|
||||
#endif
|
||||
|
||||
#if !NET5_0_OR_GREATER
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "6.0.100",
|
||||
"rollForward": "latestMinor",
|
||||
"rollForward": "latestMajor",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user