Compare commits

..

12 Commits

Author SHA1 Message Date
Alexandre Mutel
5e3416f8b7 Merge pull request #726 from mkapahnke/make_allow_null_internal
Make AllowNull internal to prevent conflicts
2023-08-04 06:40:22 +02:00
Alexandre Mutel
012a57d361 Merge pull request #724 from DeveloPoel/markdown.cs_findings
Made the markdown class not partial and fixed the ToPlainText summary.
2023-08-04 06:39:58 +02:00
Alexandre Mutel
053a18c684 Merge pull request #723 from RickStrahl/MediaExtensions-RelativePathSupport
Add relative path support for Audio and Video Urls to  MediaLinks Extension
2023-08-04 06:39:38 +02:00
Maximilian Kapahnke
13265453ac make internal 2023-07-25 18:23:23 +02:00
developoel
8ea0783834 Made the markdown class not partial and fixed the ToPlainText summary. 2023-07-18 14:09:19 +02:00
Rick Strahl
3d29430337 Update src/Markdig/Extensions/MediaLinks/MediaLinkExtension.cs
Co-authored-by: Günther Foidl <gue@korporal.at>
2023-07-13 12:04:52 -07:00
Rick Strahl
81bc58c6c9 Add support for relative Urls for Video and Audio links. 2023-07-11 14:58:43 -07:00
Rick Strahl
bfe3800130 Allow for use of .NET 7.0 SDK (Major Version Roll Forward) 2023-07-11 12:13:05 -07:00
Alexandre Mutel
b7cb169fd3 Merge pull request #710 from valterc/fix-line-group-oob
Add line count check to avoid out of range
2023-04-22 13:23:04 +01:00
Valter Costa
512b28256a Improved tests 2023-04-18 17:44:41 +01:00
Valter Costa
cd5d11eeff Fix index check 2023-04-18 17:44:23 +01:00
Valter Costa
a9118774a8 Added line count check to avoid out of bounds 2023-04-18 12:46:48 +01:00
8 changed files with 103 additions and 23 deletions

View File

@@ -36,6 +36,16 @@ public class TestMediaLinks
Assert.AreEqual(html, expected);
}
[TestCase("![static video relative path](./video.mp4)",
"<p><video width=\"500\" height=\"281\" controls=\"\"><source type=\"video/mp4\" src=\"./video.mp4\"></source></video></p>\n")]
[TestCase("![static audio relative path](./audio.mp3)",
"<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";

View File

@@ -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());
}
}

View File

@@ -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");
}
}

View File

@@ -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 &&

View File

@@ -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;

View File

@@ -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>

View File

@@ -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

View File

@@ -1,7 +1,7 @@
{
"sdk": {
"version": "6.0.100",
"rollForward": "latestMinor",
"rollForward": "latestMajor",
"allowPrerelease": false
}
}