using System.Text.RegularExpressions; using Markdig.Extensions.AutoLinks; using Markdig.Extensions.Tables; using Markdig.Syntax; using NUnit.Framework; namespace Markdig.Tests; public class MiscTests { [Test] public void LinkWithInvalidNonAsciiDomainNameIsIgnored() { // Url from https://github.com/lunet-io/markdig/issues/438 _ = Markdown.ToHtml("[minulém díle](http://V%20minulém%20díle%20jsme%20nainstalovali%20SQL%20Server,%20který%20je%20nutný%20pro%20běh%20Configuration%20Manageru.%20Dnes%20nás%20čeká%20instalace%20WSUS,%20což%20je%20produkt,%20jež%20je%20možné%20používat%20i%20jako%20samostatnou%20funkci%20ve%20Windows%20Serveru,%20který%20se%20stará%20o%20stažení%20a%20instalaci%20aktualizací%20z%20Microsoft%20Update%20na%20klientské%20počítače.%20Stejně%20jako%20v%20předchozích%20dílech,%20tak%20i%20v%20tomto%20si%20ukážeme%20obě%20varianty%20instalace%20–%20a%20to%20jak%20instalaci%20z%20PowerShellu,%20tak%20instalaci%20pomocí%20GUI.) "); // Valid IDN TestParser.TestSpec("[foo](http://ünicode.com)", "
"); TestParser.TestSpec("[foo](http://ünicode.ünicode.com)", ""); // Invalid IDN TestParser.TestSpec("[foo](http://ünicode..com)", ""); } [TestCase("link [foo [bar]]")] // https://spec.commonmark.org/0.29/#example-508 [TestCase("link [foo][bar]")] [TestCase("link [][foo][bar][]")] [TestCase("link [][foo][bar][[]]")] [TestCase("link [foo] [bar]")] [TestCase("link [[foo] [] [bar] [[abc]def]]")] [TestCase("[]")] [TestCase("[ ]")] [TestCase("[bar][]")] [TestCase("[bar][ foo]")] [TestCase("[bar][foo ][]")] [TestCase("[bar][fo[ ]o ][][]")] [TestCase("[a]b[c[d[e]f]g]h")] [TestCase("a[b[c[d]e]f[g]h]i foo [j]k[l[m]n]o")] [TestCase("a[b[c[d]e]f[g]h]i[] [][foo][bar][] foo [j]k[l[m]n]o")] [TestCase("a[b[c[d]e]f[g]h]i foo [j]k[l[m]n]o[][]")] public void LinkTextMayContainBalancedBrackets(string linkText) { string markdown = $"[{linkText}](/uri)"; string expected = $@""; TestParser.TestSpec(markdown, expected); // Make the link text unbalanced foreach (var bracketIndex in linkText .Select((c, i) => new Tuplehttps://foo.bar/path/\#m4mv5W0GYKZpGvfA.97
"; TestParser.TestSpec($"<{input}>", expected); TestParser.TestSpec(input, expected, "autolinks|advanced"); } [Test] public void IsIssue365Corrected() { // The scheme must be escaped too... string input = "\"://)"; string expected = "9&ddr;&*&ddr;&de��__
"); } [Test] public void TestInvalidCharacterHandling() { var input = File.ReadAllText(Path.Combine(TestParser.TestsDirectory, "ArgumentOutOfRangeException.md")); _ = Markdown.ToHtml(input); } [Test] public void TestInvalidCodeEscape() { var input = "```**Header** "; _ = Markdown.ToHtml(input); } [Test] public void TestEmphasisAndHtmlEntity() { var markdownText = "*Unlimited-Fun®*®"; TestParser.TestSpec(markdownText, "Unlimited-Fun®®
"); } [Test] public void TestThematicInsideCodeBlockInsideList() { var input = @"1. In the : ``` Id DisplayName Description -- ----------- ----------- 62375ab9-6b52-47ed-826b-58e47e0e304b Group.Unified ... ```"; TestParser.TestSpec(input, @"In the :
Id DisplayName Description
-- ----------- -----------
62375ab9-6b52-47ed-826b-58e47e0e304b Group.Unified ...
\\("); var test2 = html.Contains("\\)
"); if (!test1 || !test2) { Console.WriteLine(html); } Assert.IsTrue(test1, "Leading bracket missing"); Assert.IsTrue(test2, "Trailing bracket missing"); } [Test] public void BlockMathExpression() { string math = @"Math expressions $$ \frac{n!}{k!(n-k)!} = \binom{n}{k} $$ "; var pl = new MarkdownPipelineBuilder().UseMathematics().Build(); // UseEmphasisExtras(EmphasisExtraOptions.Subscript).Build() var html = Markdown.ToHtml(math, pl); var test1 = html.Contains("Foo\n===
", noHeadingsPipeline); TestParser.TestSpec("# Heading 1", "# Heading 1
", noHeadingsPipeline); // Does not also disable link reference definitions TestParser.TestSpec("[Foo]\n\n[Foo]: bar", ""); TestParser.TestSpec("[Foo]\n\n[Foo]: bar", "", noHeadingsPipeline); } [Test] public void CanOpenAutoLinksInNewWindow() { var pipeline = new MarkdownPipelineBuilder().UseAutoLinks().Build(); var newWindowPipeline = new MarkdownPipelineBuilder().UseAutoLinks(new AutoLinkOptions() { OpenInNewWindow = true }).Build(); TestParser.TestSpec("www.foo.bar", "", pipeline); TestParser.TestSpec("www.foo.bar", "", newWindowPipeline); } [Test] public void CanUseHttpsPrefixForWWWAutoLinks() { var pipeline = new MarkdownPipelineBuilder().UseAutoLinks().Build(); var httpsPipeline = new MarkdownPipelineBuilder().UseAutoLinks(new AutoLinkOptions() { UseHttpsForWWWLinks = true }).Build(); TestParser.TestSpec("www.foo.bar", "", pipeline); TestParser.TestSpec("www.foo.bar", "", httpsPipeline); } [Test] public void RootInlineHasCorrectSourceSpan() { var pipeline = new MarkdownPipelineBuilder().UsePreciseSourceLocation().Build(); pipeline.TrackTrivia = true; var document = Markdown.Parse("0123456789\n", pipeline); var expectedSourceSpan = new SourceSpan(0, 10); Assert.That(((LeafBlock)document.LastChild).Inline.Span == expectedSourceSpan); } [Test] public void RootInlineInTableCellHasCorrectSourceSpan() { var pipeline = new MarkdownPipelineBuilder().UsePreciseSourceLocation().UseAdvancedExtensions().Build(); pipeline.TrackTrivia = true; var document = Markdown.Parse("| a | b |\n| --- | --- |\n| *dest*| 6 | 1 |
Note
[!NOTE] The second one is not a note.
"; TestParser.TestSpec(input, expected, new MarkdownPipelineBuilder().UseAlertBlocks().Build()); } [Test] public void TestNestedAlertInsideBlockquote() { // >>[!NOTE] should become a blockquote wrapping an alert when AllowNestedAlerts is enabled var input = @">>[!NOTE] Also a note. "; var expected = @"[!NOTE] Also not a note.
"; TestParser.TestSpec(input, expected, new MarkdownPipelineBuilder().UseAlertBlocks(allowNestedAlerts: true).Build()); } [Test] public void TestNestedAlertInsideAlert() { // An alert inside another alert is never recognized, even with AllowNestedAlerts var input = @">[!NOTE] > >[!TIP] > > A tip inside a note "; var expected = @"Note
Also a note.
Note
[!TIP] A tip inside a note
Note
A note inside a list item
Note
A note inside a nested list item
"; TestParser.TestSpec(input, expected); } [Test] public void TestIssue845ListItemBlankLine() { TestParser.TestSpec("-\n\n foo",@"
- Unordered 1 QL2 level 1 no space sep Continued 1
- Unordered 2 level 1
- Ordered 1 QL2 level 1 Continued 1
Not continued QL3
Ordered 2 QL2 level 1 Continued 2a
Continued 2b
Continued 2c
Ordered 3 QL2 level 2 Continued 3a
Continued 3b
foo
"); TestParser.TestSpec("-\n-\n\n foo",@"foo
"); TestParser.TestSpec("-\n\n-\n\n foo",@"foo
"); } }