Compare commits

...

17 Commits

Author SHA1 Message Date
Alexandre Mutel
266e0c8bfd Fix consecutive footnotes without blanklines between (issue #26) 2016-06-24 06:01:53 +09:00
Alexandre Mutel
f5c07dbab5 Bump to 0.5.12 2016-06-24 05:43:17 +09:00
Alexandre Mutel
c8a28a1ad7 Fix an issue where a consecutive footnote is parsed as a paragraph (issue #26) 2016-06-24 05:42:36 +09:00
Alexandre Mutel
72cc454314 Remove backsticks in SmartyPantsInlineParser. Rename SmaryPantsInlineParser to SmartyPantsInlineParser 2016-06-24 05:27:12 +09:00
Alexandre Mutel
7fe2c1f939 Remove OrderedList.ReplacyBy method, as it is not used and might be not predictable (issue #25) 2016-06-24 05:25:54 +09:00
Alexandre Mutel
087e7a68b6 Fix emoji parsing and allow them only if they are surrounded by spaces (issue #15) 2016-06-23 17:28:33 +09:00
Alexandre Mutel
abeabf15a1 Remove non necessary check in HtmlAttributes.CopyTo 2016-06-23 11:49:01 +09:00
Alexandre Mutel
f9bfcaab7b Bump version to 0.5.11 2016-06-23 11:46:22 +09:00
Alexandre Mutel
afa0182f02 Fix ArgumentNullReference exception in HtmlAttributes.CopyTo (issue #23) 2016-06-23 11:46:07 +09:00
Alexandre Mutel
b83de5934d Bump version to 0.5.10 2016-06-23 05:52:06 +09:00
Alexandre Mutel
c294d3bfb4 Improve compact method for tests taking into account \r\n and \r 2016-06-23 05:52:06 +09:00
Alexandre Mutel
a7cdb2351a Fix regression for html block parsing (issue #21) 2016-06-23 05:52:05 +09:00
Alexandre Mutel
46ef21a3ed Merge pull request #19 from jorrit/patch-1
Fix typo in MarkdownExtensions.cs
2016-06-22 20:55:51 +09:00
Jorrit Schippers
18c8d0178c Fix typo in MarkdownExtensions.cs 2016-06-22 13:55:09 +02:00
Alexandre Mutel
ebc79dafbd Bump version to 0.5.9 2016-06-22 08:37:37 +09:00
Alexandre Mutel
a1d2467643 Fix bug for deep nested list items that were incorrectly detected (not CommonMark compliant. Check with CommonMark specs to add a test case) 2016-06-22 08:35:42 +09:00
Alexandre Mutel
8220f0fa56 Fix ArgumentOutOfRangeException in Block.FindClosestLine. Add tests for Pragmalines 2016-06-22 08:35:08 +09:00
21 changed files with 502 additions and 155 deletions

View File

@@ -59,9 +59,11 @@
<DesignTime>True</DesignTime>
<DependentUpon>Specs.tt</DependentUpon>
</Compile>
<Compile Include="TestHtmlAttributes.cs" />
<Compile Include="TestHtmlHelper.cs" />
<Compile Include="TestLineReader.cs" />
<Compile Include="TestLinkHelper.cs" />
<Compile Include="TestPragmaLines.cs" />
<Compile Include="TestSourcePosition.cs" />
<Compile Include="TestStringSliceList.cs" />
<Compile Include="TestPlayParser.cs" />

View File

@@ -11,3 +11,11 @@ This is a test with a :) and a :angry: smiley
.
<p>This is a test with a 😃 and a 😠 smiley</p>
````````````````````````````````
An emoji needs to be preceded by a space and followed by a space:
```````````````````````````````` example
These are not:) an :)emoji with a:) x:angry:x
.
<p>These are not:) an :)emoji with a:) x:angry:x</p>
````````````````````````````````

View File

@@ -61,3 +61,60 @@ multi-paragraph list items.<a href="#fnref:3" class="footnote-back-ref">&#8617;<
</div>
````````````````````````````````
Check with mulitple consecutive footnotes:
```````````````````````````````` example
Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
[^1]: Footnote 1 text
[^2]: Footnote 2 text
a
[^3]: Footnote 3 text
[^4]: Footnote 4 text
.
<p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
<p>a</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn:1">
<p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">&#8617;</a></p></li>
<li id="fn:2">
<p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">&#8617;</a></p></li>
<li id="fn:3">
<p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">&#8617;</a></p></li>
<li id="fn:4">
<p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">&#8617;</a></p></li>
</ol>
</div>
````````````````````````````````
Another test with consecutive footnotes without a blank line separator:
```````````````````````````````` example
Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
[^1]: Footnote 1 text
[^2]: Footnote 2 text
[^3]: Footnote 3 text
[^4]: Footnote 4 text
.
<p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn:1">
<p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">&#8617;</a></p></li>
<li id="fn:2">
<p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">&#8617;</a></p></li>
<li id="fn:3">
<p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">&#8617;</a></p></li>
<li id="fn:4">
<p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">&#8617;</a></p></li>
</ol>
</div>
````````````````````````````````

View File

@@ -83,29 +83,6 @@ They are' not matching 'quotes
.
<p>They are' not matching 'quotes</p>
````````````````````````````````
Double quotes using ``` `` ``` are working if they match another `''` pair, and there is no other double quotes on the line (otherwise they would be parsed as a code span):
```````````````````````````````` example
This is ``a double quote''
.
<p>This is &ldquo;a double quote&rdquo;</p>
````````````````````````````````
```````````````````````````````` example
This is ``a code span''``
.
<p>This is <code>a code span''</code></p>
````````````````````````````````
```````````````````````````````` example
hello ``there```
test
.
<p>hello &ldquo;there&rdquo;`
test</p>
````````````````````````````````
An emphasis starting inside left/right quotes will span over the right quote:
```````````````````````````````` example

View File

@@ -3811,6 +3811,7 @@ namespace Markdig.Tests
// main :: IO ()
// main = print $ parseTags tags
// </code></pre>
// okay
//
// Should be rendered as:
// <pre language="haskell"><code>
@@ -3819,9 +3820,10 @@ namespace Markdig.Tests
// main :: IO ()
// main = print $ parseTags tags
// </code></pre>
// <p>okay</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 134, "Leaf blocks HTML blocks");
TestParser.TestSpec("<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>", "<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>", "");
TestParser.TestSpec("<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>\nokay", "<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>\n<p>okay</p>", "");
}
}
// A script tag (type 1):
@@ -3840,6 +3842,7 @@ namespace Markdig.Tests
//
// document.getElementById("demo").innerHTML = "Hello JavaScript!";
// </script>
// okay
//
// Should be rendered as:
// <script type="text/javascript">
@@ -3847,9 +3850,10 @@ namespace Markdig.Tests
//
// document.getElementById("demo").innerHTML = "Hello JavaScript!";
// </script>
// <p>okay</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 135, "Leaf blocks HTML blocks");
TestParser.TestSpec("<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>", "<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>", "");
TestParser.TestSpec("<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>\nokay", "<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>\n<p>okay</p>", "");
}
}
// A style tag (type 1):
@@ -3869,6 +3873,7 @@ namespace Markdig.Tests
//
// p {color:blue;}
// </style>
// okay
//
// Should be rendered as:
// <style
@@ -3877,9 +3882,10 @@ namespace Markdig.Tests
//
// p {color:blue;}
// </style>
// <p>okay</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 136, "Leaf blocks HTML blocks");
TestParser.TestSpec("<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>", "<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>", "");
TestParser.TestSpec("<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>\nokay", "<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>\n<p>okay</p>", "");
}
}
// If there is no matching end tag, the block will end at the
@@ -4044,15 +4050,17 @@ namespace Markdig.Tests
//
// bar
// baz -->
// okay
//
// Should be rendered as:
// <!-- Foo
//
// bar
// baz -->
// <p>okay</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 143, "Leaf blocks HTML blocks");
TestParser.TestSpec("<!-- Foo\n\nbar\n baz -->", "<!-- Foo\n\nbar\n baz -->", "");
TestParser.TestSpec("<!-- Foo\n\nbar\n baz -->\nokay", "<!-- Foo\n\nbar\n baz -->\n<p>okay</p>", "");
}
}
// A processing instruction (type 3):
@@ -4071,6 +4079,7 @@ namespace Markdig.Tests
// echo '>';
//
// ?>
// okay
//
// Should be rendered as:
// <?php
@@ -4078,9 +4087,10 @@ namespace Markdig.Tests
// echo '>';
//
// ?>
// <p>okay</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 144, "Leaf blocks HTML blocks");
TestParser.TestSpec("<?php\n\n echo '>';\n\n?>", "<?php\n\n echo '>';\n\n?>", "");
TestParser.TestSpec("<?php\n\n echo '>';\n\n?>\nokay", "<?php\n\n echo '>';\n\n?>\n<p>okay</p>", "");
}
}
// A declaration (type 4):
@@ -4126,6 +4136,7 @@ namespace Markdig.Tests
// }
// }
// ]]>
// okay
//
// Should be rendered as:
// <![CDATA[
@@ -4140,9 +4151,10 @@ namespace Markdig.Tests
// }
// }
// ]]>
// <p>okay</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 146, "Leaf blocks HTML blocks");
TestParser.TestSpec("<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>", "<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>", "");
TestParser.TestSpec("<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>\nokay", "<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>\n<p>okay</p>", "");
}
}
// The opening tag can be indented 1-3 spaces, but not 4:
@@ -5387,8 +5399,8 @@ namespace Markdig.Tests
TestParser.TestSpec(" > # Foo\n > bar\n > baz", "<pre><code>&gt; # Foo\n&gt; bar\n&gt; baz\n</code></pre>", "");
}
}
// The Laziness clause allows us to omit the `>` before a
// paragraph continuation line:
// The Laziness clause allows us to omit the `>` before
// [paragraph continuation text]:
[TestFixture]
public partial class TestContainerblocksBlockquotes
{
@@ -5561,8 +5573,8 @@ namespace Markdig.Tests
TestParser.TestSpec("> ```\nfoo\n```", "<blockquote>\n<pre><code></code></pre>\n</blockquote>\n<p>foo</p>\n<pre><code></code></pre>", "");
}
}
// Note that in the following case, we have a paragraph
// continuation line:
// Note that in the following case, we have a [lazy
// continuation line]:
[TestFixture]
public partial class TestContainerblocksBlockquotes
{
@@ -5595,7 +5607,7 @@ namespace Markdig.Tests
//
// the `- bar` is indented too far to start a list, and can't
// be an indented code block because indented code blocks cannot
// interrupt paragraphs, so it is a [paragraph continuation line].
// interrupt paragraphs, so it is [paragraph continuation text].
//
// A block quote can be empty:
[TestFixture]
@@ -7286,6 +7298,7 @@ namespace Markdig.Tests
// - foo
// - bar
// - baz
// - boo
//
// Should be rendered as:
// <ul>
@@ -7293,7 +7306,11 @@ namespace Markdig.Tests
// <ul>
// <li>bar
// <ul>
// <li>baz</li>
// <li>baz
// <ul>
// <li>boo</li>
// </ul>
// </li>
// </ul>
// </li>
// </ul>
@@ -7301,7 +7318,7 @@ namespace Markdig.Tests
// </ul>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 254, "Container blocks List items");
TestParser.TestSpec("- foo\n - bar\n - baz", "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>baz</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>", "");
TestParser.TestSpec("- foo\n - bar\n - baz\n - boo", "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>baz\n<ul>\n<li>boo</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>", "");
}
}
// One is not enough:
@@ -7318,16 +7335,18 @@ namespace Markdig.Tests
// - foo
// - bar
// - baz
// - boo
//
// Should be rendered as:
// <ul>
// <li>foo</li>
// <li>bar</li>
// <li>baz</li>
// <li>boo</li>
// </ul>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 255, "Container blocks List items");
TestParser.TestSpec("- foo\n - bar\n - baz", "<ul>\n<li>foo</li>\n<li>bar</li>\n<li>baz</li>\n</ul>", "");
TestParser.TestSpec("- foo\n - bar\n - baz\n - boo", "<ul>\n<li>foo</li>\n<li>bar</li>\n<li>baz</li>\n<li>boo</li>\n</ul>", "");
}
}
// Here we need four, because the list marker is wider:
@@ -13868,7 +13887,7 @@ namespace Markdig.Tests
// [link reference definition] elsewhere in the
// document and is not followed by `[]` or a link label.
// The contents of the first link label are parsed as inlines,
// which are used as the link's text. the link's URI and title
// which are used as the link's text. The link's URI and title
// are provided by the matching link reference definition.
// Thus, `[foo]` is equivalent to `[foo][]`.
[TestFixture]
@@ -17103,6 +17122,88 @@ namespace Markdig.Tests
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 1, "Extensions Footontes");
TestParser.TestSpec("Here is a footnote reference,[^1] and another.[^longnote]\n\nThis is another reference to [^1]\n\n[^1]: Here is the footnote.\n\nAnd another reference to [^longnote]\n\n[^longnote]: Here's one with multiple blocks.\n\n Subsequent paragraphs are indented to show that they\nbelong to the previous footnote.\n\n > This is a block quote\n > Inside a footnote\n\n { some.code }\n\n The whole paragraph can be indented, or just the first\n line. In this way, multi-paragraph footnotes work like\n multi-paragraph list items.\n\nThis paragraph won't be part of the note, because it\nisn't indented.", "<p>Here is a footnote reference,<a id=\"fnref:1\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a> and another.<a id=\"fnref:3\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a></p>\n<p>This is another reference to <a id=\"fnref:2\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a></p>\n<p>And another reference to <a id=\"fnref:4\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a></p>\n<p>This paragraph won't be part of the note, because it\nisn't indented.</p>\n<div class=\"footnotes\">\n<hr />\n<ol>\n<li id=\"fn:1\">\n<p>Here is the footnote.<a href=\"#fnref:1\" class=\"footnote-back-ref\">&#8617;</a><a href=\"#fnref:2\" class=\"footnote-back-ref\">&#8617;</a></p>\n</li>\n<li id=\"fn:2\">\n<p>Here's one with multiple blocks.</p>\n<p>Subsequent paragraphs are indented to show that they\nbelong to the previous footnote.</p>\n<blockquote>\n<p>This is a block quote\nInside a footnote</p>\n</blockquote>\n<pre><code>{ some.code }\n</code></pre>\n<p>The whole paragraph can be indented, or just the first\nline. In this way, multi-paragraph footnotes work like\nmulti-paragraph list items.<a href=\"#fnref:3\" class=\"footnote-back-ref\">&#8617;</a><a href=\"#fnref:4\" class=\"footnote-back-ref\">&#8617;</a></p>\n</li>\n</ol>\n</div>", "footnotes");
}
}
// Check with mulitple consecutive footnotes:
[TestFixture]
public partial class TestExtensionsFootontes
{
[Test]
public void Example002()
{
// Example 2
// Section: Extensions Footontes
//
// The following CommonMark:
// Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
//
// [^1]: Footnote 1 text
//
// [^2]: Footnote 2 text
//
// a
//
// [^3]: Footnote 3 text
//
// [^4]: Footnote 4 text
//
// Should be rendered as:
// <p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
// <p>a</p>
// <div class="footnotes">
// <hr />
// <ol>
// <li id="fn:1">
// <p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">&#8617;</a></p></li>
// <li id="fn:2">
// <p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">&#8617;</a></p></li>
// <li id="fn:3">
// <p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">&#8617;</a></p></li>
// <li id="fn:4">
// <p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">&#8617;</a></p></li>
// </ol>
// </div>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 2, "Extensions Footontes");
TestParser.TestSpec("Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].\n\n[^1]: Footnote 1 text\n\n[^2]: Footnote 2 text\n\na\n\n[^3]: Footnote 3 text\n\n[^4]: Footnote 4 text", "<p>Here is a footnote<a id=\"fnref:1\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a>. And another one<a id=\"fnref:2\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a>. And a third one<a id=\"fnref:3\" href=\"#fn:3\" class=\"footnote-ref\"><sup>3</sup></a>. And a fourth<a id=\"fnref:4\" href=\"#fn:4\" class=\"footnote-ref\"><sup>4</sup></a>.</p>\n<p>a</p>\n<div class=\"footnotes\">\n<hr />\n<ol>\n<li id=\"fn:1\">\n<p>Footnote 1 text<a href=\"#fnref:1\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n<li id=\"fn:2\">\n<p>Footnote 2 text<a href=\"#fnref:2\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n<li id=\"fn:3\">\n<p>Footnote 3 text<a href=\"#fnref:3\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n<li id=\"fn:4\">\n<p>Footnote 4 text<a href=\"#fnref:4\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n</ol>\n</div>", "footnotes");
}
}
// Another test with consecutive footnotes without a blank line separator:
[TestFixture]
public partial class TestExtensionsFootontes
{
[Test]
public void Example003()
{
// Example 3
// Section: Extensions Footontes
//
// The following CommonMark:
// Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
//
// [^1]: Footnote 1 text
// [^2]: Footnote 2 text
// [^3]: Footnote 3 text
// [^4]: Footnote 4 text
//
// Should be rendered as:
// <p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
// <div class="footnotes">
// <hr />
// <ol>
// <li id="fn:1">
// <p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">&#8617;</a></p></li>
// <li id="fn:2">
// <p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">&#8617;</a></p></li>
// <li id="fn:3">
// <p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">&#8617;</a></p></li>
// <li id="fn:4">
// <p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">&#8617;</a></p></li>
// </ol>
// </div>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 3, "Extensions Footontes");
TestParser.TestSpec("Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].\n\n[^1]: Footnote 1 text\n[^2]: Footnote 2 text\n[^3]: Footnote 3 text\n[^4]: Footnote 4 text", "<p>Here is a footnote<a id=\"fnref:1\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a>. And another one<a id=\"fnref:2\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a>. And a third one<a id=\"fnref:3\" href=\"#fn:3\" class=\"footnote-ref\"><sup>3</sup></a>. And a fourth<a id=\"fnref:4\" href=\"#fn:4\" class=\"footnote-ref\"><sup>4</sup></a>.</p>\n<div class=\"footnotes\">\n<hr />\n<ol>\n<li id=\"fn:1\">\n<p>Footnote 1 text<a href=\"#fnref:1\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n<li id=\"fn:2\">\n<p>Footnote 2 text<a href=\"#fnref:2\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n<li id=\"fn:3\">\n<p>Footnote 3 text<a href=\"#fnref:3\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n<li id=\"fn:4\">\n<p>Footnote 4 text<a href=\"#fnref:4\" class=\"footnote-back-ref\">&#8617;</a></p></li>\n</ol>\n</div>", "footnotes");
}
}
// # Extensions
//
@@ -17978,6 +18079,26 @@ namespace Markdig.Tests
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 1, "Extensions Emoji");
TestParser.TestSpec("This is a test with a :) and a :angry: smiley", "<p>This is a test with a 😃 and a 😠 smiley</p>", "emojis");
}
}
// An emoji needs to be preceded by a space and followed by a space:
[TestFixture]
public partial class TestExtensionsEmoji
{
[Test]
public void Example002()
{
// Example 2
// Section: Extensions Emoji
//
// The following CommonMark:
// These are not:) an :)emoji with a:) x:angry:x
//
// Should be rendered as:
// <p>These are not:) an :)emoji with a:) x:angry:x</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 2, "Extensions Emoji");
TestParser.TestSpec("These are not:) an :)emoji with a:) x:angry:x", "<p>These are not:) an :)emoji with a:) x:angry:x</p>", "emojis");
}
}
// # Extensions
//
@@ -18937,7 +19058,7 @@ namespace Markdig.Tests
TestParser.TestSpec("They are' not matching 'quotes", "<p>They are' not matching 'quotes</p>", "smartypants");
}
}
// Double quotes using ``` `` ``` are working if they match another `''` pair, and there is no other double quotes on the line (otherwise they would be parsed as a code span):
// An emphasis starting inside left/right quotes will span over the right quote:
[TestFixture]
public partial class TestExtensionsSmartyPantsQuotes
{
@@ -18948,72 +19069,12 @@ namespace Markdig.Tests
// Section: Extensions SmartyPants Quotes
//
// The following CommonMark:
// This is ``a double quote''
//
// Should be rendered as:
// <p>This is &ldquo;a double quote&rdquo;</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 13, "Extensions SmartyPants Quotes");
TestParser.TestSpec("This is ``a double quote''", "<p>This is &ldquo;a double quote&rdquo;</p>", "smartypants");
}
}
[TestFixture]
public partial class TestExtensionsSmartyPantsQuotes
{
[Test]
public void Example014()
{
// Example 14
// Section: Extensions SmartyPants Quotes
//
// The following CommonMark:
// This is ``a code span''``
//
// Should be rendered as:
// <p>This is <code>a code span''</code></p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 14, "Extensions SmartyPants Quotes");
TestParser.TestSpec("This is ``a code span''`` ", "<p>This is <code>a code span''</code></p>", "smartypants");
}
}
[TestFixture]
public partial class TestExtensionsSmartyPantsQuotes
{
[Test]
public void Example015()
{
// Example 15
// Section: Extensions SmartyPants Quotes
//
// The following CommonMark:
// hello ``there```
// test
//
// Should be rendered as:
// <p>hello &ldquo;there&rdquo;`
// test</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 15, "Extensions SmartyPants Quotes");
TestParser.TestSpec("hello ``there```\ntest", "<p>hello &ldquo;there&rdquo;`\ntest</p>", "smartypants");
}
}
// An emphasis starting inside left/right quotes will span over the right quote:
[TestFixture]
public partial class TestExtensionsSmartyPantsQuotes
{
[Test]
public void Example016()
{
// Example 16
// Section: Extensions SmartyPants Quotes
//
// The following CommonMark:
// This is "a *text" with an emphasis*
//
// Should be rendered as:
// <p>This is &ldquo;a <em>text&rdquo; with an emphasis</em></p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 16, "Extensions SmartyPants Quotes");
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 13, "Extensions SmartyPants Quotes");
TestParser.TestSpec("This is \"a *text\" with an emphasis*", "<p>This is &ldquo;a <em>text&rdquo; with an emphasis</em></p>", "smartypants");
}
}
@@ -19022,9 +19083,9 @@ namespace Markdig.Tests
public partial class TestExtensionsSmartyPantsSeparators
{
[Test]
public void Example017()
public void Example014()
{
// Example 17
// Example 14
// Section: Extensions SmartyPants Separators
//
// The following CommonMark:
@@ -19033,7 +19094,7 @@ namespace Markdig.Tests
// Should be rendered as:
// <p>This is a &ndash; text</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 17, "Extensions SmartyPants Separators");
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 14, "Extensions SmartyPants Separators");
TestParser.TestSpec("This is a -- text", "<p>This is a &ndash; text</p>", "smartypants");
}
}
@@ -19041,9 +19102,9 @@ namespace Markdig.Tests
public partial class TestExtensionsSmartyPantsSeparators
{
[Test]
public void Example018()
public void Example015()
{
// Example 18
// Example 15
// Section: Extensions SmartyPants Separators
//
// The following CommonMark:
@@ -19052,7 +19113,7 @@ namespace Markdig.Tests
// Should be rendered as:
// <p>This is a &mdash; text</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 18, "Extensions SmartyPants Separators");
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 15, "Extensions SmartyPants Separators");
TestParser.TestSpec("This is a --- text", "<p>This is a &mdash; text</p>", "smartypants");
}
}
@@ -19060,9 +19121,9 @@ namespace Markdig.Tests
public partial class TestExtensionsSmartyPantsSeparators
{
[Test]
public void Example019()
public void Example016()
{
// Example 19
// Example 16
// Section: Extensions SmartyPants Separators
//
// The following CommonMark:
@@ -19071,7 +19132,7 @@ namespace Markdig.Tests
// Should be rendered as:
// <p>This is a en ellipsis&hellip;</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 19, "Extensions SmartyPants Separators");
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 16, "Extensions SmartyPants Separators");
TestParser.TestSpec("This is a en ellipsis...", "<p>This is a en ellipsis&hellip;</p>", "smartypants");
}
}

View File

@@ -0,0 +1,96 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Markdig.Renderers.Html;
using NUnit.Framework;
using System.Collections.Generic;
namespace Markdig.Tests
{
[TestFixture()]
public class TestHtmlAttributes
{
[Test]
public void TestAddClass()
{
var attributes = new HtmlAttributes();
attributes.AddClass("test");
Assert.NotNull(attributes.Classes);
Assert.AreEqual(new List<string>() { "test" }, attributes.Classes);
attributes.AddClass("test");
Assert.AreEqual(1, attributes.Classes.Count);
attributes.AddClass("test1");
Assert.AreEqual(new List<string>() { "test", "test1" }, attributes.Classes);
}
[Test]
public void TestAddProperty()
{
var attributes = new HtmlAttributes();
attributes.AddProperty("key1", "1");
Assert.NotNull(attributes.Properties);
Assert.AreEqual(new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("key1", "1") }, attributes.Properties);
attributes.AddPropertyIfNotExist("key1", "1");
Assert.NotNull(attributes.Properties);
Assert.AreEqual(new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("key1", "1") }, attributes.Properties);
attributes.AddPropertyIfNotExist("key2", "2");
Assert.AreEqual(new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("key1", "1"), new KeyValuePair<string, string>("key2", "2") }, attributes.Properties);
}
[Test]
public void TestCopyTo()
{
var from = new HtmlAttributes();
from.AddClass("test");
from.AddProperty("key1", "1");
var to = new HtmlAttributes();
from.CopyTo(to);
Assert.True(ReferenceEquals(from.Classes, to.Classes));
Assert.True(ReferenceEquals(from.Properties, to.Properties));
// From: Classes From: Properties To: Classes To: Properties
// test1: null null null null
from = new HtmlAttributes();
to = new HtmlAttributes();
from.CopyTo(to, false, false);
Assert.Null(to.Classes);
Assert.Null(to.Properties);
// test2: ["test"] ["key1", "1"] null null
from = new HtmlAttributes();
to = new HtmlAttributes();
from.AddClass("test");
from.AddProperty("key1", "1");
from.CopyTo(to, false, false);
Assert.AreEqual(new List<string>() { "test" }, to.Classes);
Assert.AreEqual(new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("key1", "1")}, to.Properties);
// test3: null null ["test"] ["key1", "1"]
from = new HtmlAttributes();
to = new HtmlAttributes();
to.AddClass("test");
to.AddProperty("key1", "1");
from.CopyTo(to, false, false);
Assert.AreEqual(new List<string>() { "test" }, to.Classes);
Assert.AreEqual(new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("key1", "1") }, to.Properties);
// test4: ["test1"] ["key2", "2"] ["test"] ["key1", "1"]
from = new HtmlAttributes();
to = new HtmlAttributes();
from.AddClass("test1");
from.AddProperty("key2", "2");
to.AddClass("test");
to.AddProperty("key1", "1");
from.CopyTo(to, false, false);
Assert.AreEqual(new List<string>() { "test", "test1" }, to.Classes);
Assert.AreEqual(new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("key1", "1"), new KeyValuePair<string, string>("key2", "2") }, to.Properties);
}
}
}

View File

@@ -78,7 +78,7 @@ namespace Markdig.Tests
private static string Compact(string html)
{
// Normalize the output to make it compatible with CommonMark specs
html = html.Replace("\r", "").Trim();
html = html.Replace("\r\n", "\n").Replace(@"\r", @"\n").Trim();
html = Regex.Replace(html, @"\s+</li>", "</li>");
html = Regex.Replace(html, @"<li>\s+", "<li>");
html = html.Normalize(NormalizationForm.FormKD);

View File

@@ -27,6 +27,49 @@ Later in a text we are using HTML and it becomes an abbr tag HTML
Console.WriteLine(result);
}
[Test]
public void TestListBug()
{
// TODO: Add this test back to the CommonMark specs
var text = @"- item1
- item2
- item3
- item4";
TestParser.TestSpec(text, @"<ul>
<li>item1
<ul>
<li>item2
<ul>
<li>item3
<ul>
<li>item4</li>
</ul></li>
</ul></li>
</ul></li>
</ul>
");
}
[Test]
public void TestHtmlBug()
{
TestParser.TestSpec(@" # header1
<pre class='copy'>
blabla
</pre>
# header2
", @"<h1>header1</h1>
<pre class='copy'>
blabla
</pre>
<h1>header2</h1>");
}
[Test]
public void TestBugAdvancaed()
{

View File

@@ -0,0 +1,81 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Markdig.Renderers;
using Markdig.Syntax;
using NUnit.Framework;
namespace Markdig.Tests
{
[TestFixture]
public class TestPragmaLines
{
[Test]
public void TestFindClosest()
{
var doc = Markdown.Parse(
"test1\n" + // 0
"\n" + // 1
"test2\n" + // 2
"\n" + // 3
"test3\n" + // 4
"\n" + // 5
"test4\n" + // 6
"\n" + // 7
"# Heading\n" + // 8
"\n" + // 9
"Long para\n" + // 10
"on multiple\n" + // 11
"lines\n" + // 12
"to check that\n" + // 13
"lines are\n" + // 14
"correctly \n" + // 15
"found\n" + // 16
"\n" + // 17
"- item1\n" + // 18
"- item2\n" + // 19
"- item3\n" + // 20
"\n" + // 21
"This is a last paragraph\n" // 22
, new MarkdownPipelineBuilder().UsePragmaLines().Build());
foreach (var exact in new int[] {0, 2, 4, 6, 8, 10, 18, 19, 20, 22})
{
Assert.AreEqual(exact, doc.FindClosestLine(exact));
}
Assert.AreEqual(22, doc.FindClosestLine(23));
Assert.AreEqual(10, doc.FindClosestLine(11));
Assert.AreEqual(10, doc.FindClosestLine(12));
Assert.AreEqual(10, doc.FindClosestLine(13));
Assert.AreEqual(18, doc.FindClosestLine(14)); // > 50% of the paragraph, we switch to next
Assert.AreEqual(18, doc.FindClosestLine(15));
Assert.AreEqual(18, doc.FindClosestLine(16));
}
[Test]
public void TestFindClosest1()
{
var text =
"- item1\n" + // 0
" - item11\n" + // 1
" - item12\n" + // 2
" - item121\n" + // 3
" - item13\n" + // 4
" - item131\n" + // 5
" - item1311\n"; // 6
var pipeline = new MarkdownPipelineBuilder().UsePragmaLines().Build();
var doc = Markdown.Parse(text, pipeline);
for (int exact = 0; exact < 7; exact++)
{
Assert.AreEqual(exact, doc.FindClosestLine(exact));
}
Assert.AreEqual(6, doc.FindClosestLine(50));
}
}
}

View File

@@ -67,18 +67,34 @@ namespace Markdig.Extensions.Emoji
public override bool Match(InlineProcessor processor, ref StringSlice slice)
{
string match;
// Previous char must be a space
if (!slice.PeekCharExtra(-1).IsWhiteSpaceOrZero())
{
return false;
}
// Try to match an existing emoji
var startPosition = slice.Start;
if (!textMatchHelper.TryMatch(slice.Text, slice.Start, slice.Length, out match))
{
return false;
}
// Following char must be a space
if (!slice.PeekCharExtra(match.Length).IsWhiteSpaceOrZero())
{
return false;
}
// If we have a smiley, we decode it to emoji
string emoji;
if (!SmileyToEmoji.TryGetValue(match, out emoji))
{
emoji = match;
}
// Decode the eomji to unicode
string unicode;
if (!EmojiToUnicode.TryGetValue(emoji, out unicode))
{

View File

@@ -26,9 +26,14 @@ namespace Markdig.Extensions.Footnotes
}
public override BlockState TryOpen(BlockProcessor processor)
{
return TryOpen(processor, false);
}
private BlockState TryOpen(BlockProcessor processor, bool isContinue)
{
// We expect footnote to appear only at document level and not indented more than a code indent block
if (processor.IsCodeIndent || processor.CurrentContainer.GetType() != typeof(MarkdownDocument) )
if (processor.IsCodeIndent || (!isContinue && processor.CurrentContainer.GetType() != typeof(MarkdownDocument)) || (isContinue && !(processor.CurrentContainer is Footnote)))
{
return BlockState.None;
}
@@ -42,7 +47,7 @@ namespace Markdig.Extensions.Footnotes
processor.GoToColumn(saved);
return BlockState.None;
}
// Advance the column
int deltaColumn = processor.Start - start;
processor.Column = processor.Column + deltaColumn;
@@ -88,9 +93,23 @@ namespace Markdig.Extensions.Footnotes
return BlockState.ContinueDiscard;
}
if (footnote.IsLastLineEmpty && processor.Column == 0)
if (processor.Column == 0)
{
return BlockState.Break;
if (footnote.IsLastLineEmpty)
{
// Close the current footnote
processor.Close(footnote);
// Parse any opening footnote
return TryOpen(processor);
}
// Make sure that consecutive footnotes without a blanklines are parsed correctly
if (TryOpen(processor, true) == BlockState.Continue)
{
processor.Close(footnote);
return BlockState.Continue;
}
}
}
footnote.IsLastLineEmpty = false;

View File

@@ -28,10 +28,10 @@ namespace Markdig.Extensions.SmartyPants
public void Setup(MarkdownPipelineBuilder pipeline)
{
if (!pipeline.InlineParsers.Contains<SmaryPantsInlineParser>())
if (!pipeline.InlineParsers.Contains<SmartyPantsInlineParser>())
{
// Insert the parser after the code span parser
pipeline.InlineParsers.InsertAfter<CodeInlineParser>(new SmaryPantsInlineParser());
pipeline.InlineParsers.InsertAfter<CodeInlineParser>(new SmartyPantsInlineParser());
}
}

View File

@@ -11,14 +11,14 @@ namespace Markdig.Extensions.SmartyPants
/// <summary>
/// The inline parser for SmartyPants.
/// </summary>
public class SmaryPantsInlineParser : InlineParser
public class SmartyPantsInlineParser : InlineParser
{
/// <summary>
/// Initializes a new instance of the <see cref="SmaryPantsInlineParser"/> class.
/// Initializes a new instance of the <see cref="SmartyPantsInlineParser"/> class.
/// </summary>
public SmaryPantsInlineParser()
public SmartyPantsInlineParser()
{
OpeningCharacters = new[] {'`', '\'', '"', '<', '>', '.', '-'};
OpeningCharacters = new[] {'\'', '"', '<', '>', '.', '-'};
}
public override bool Match(InlineProcessor processor, ref StringSlice slice)
@@ -44,13 +44,6 @@ namespace Markdig.Extensions.SmartyPants
switch (c)
{
case '`':
if (slice.PeekChar(1) == '`')
{
slice.NextChar();
type = SmartyPantType.DoubleQuote; // We will resolve them at the end of parsing all inlines
}
break;
case '\'':
type = SmartyPantType.Quote; // We will resolve them at the end of parsing all inlines
if (slice.PeekChar(1) == '\'')

View File

@@ -101,19 +101,5 @@ namespace Markdig.Helpers
}
return false;
}
public bool ReplacyBy<TElement>(T element) where TElement : T
{
if (element == null) throw new ArgumentNullException(nameof(element));
for (int i = 0; i < Count; i++)
{
if (this[i] is TElement)
{
this[i] = element;
return true;
}
}
return false;
}
}
}

View File

@@ -249,7 +249,7 @@ namespace Markdig.Helpers
endOfIndex = 0;
for (int i = Start; i <= end; i++)
{
if (MatchLowercase(text, End, i))
if (MatchLowercase(text, End, i - Start))
{
endOfIndex = i + text.Length;
return true;

View File

@@ -155,7 +155,7 @@ namespace Markdig
}
/// <summary>
/// Uses the boostrap extension.
/// Uses the bootstrap extension.
/// </summary>
/// <param name="pipeline">The pipeline.</param>
/// <returns>The modified pipeline</returns>
@@ -442,4 +442,4 @@ namespace Markdig
return pipeline;
}
}
}
}

View File

@@ -170,7 +170,7 @@ namespace Markdig.Parsers
{
if (state.Indent > columWidth && state.IsCodeIndent)
{
state.GoToColumn(columWidth);
state.GoToColumn(state.ColumnBeforeIndent + columWidth);
}
// Update list-item source end position

View File

@@ -25,6 +25,6 @@ namespace Markdig
{
public static partial class Markdown
{
public const string Version = "0.5.8";
public const string Version = "0.5.12";
}
}

View File

@@ -118,7 +118,7 @@ namespace Markdig.Renderers.Html
}
if (htmlAttributes.Classes == null)
{
htmlAttributes.Classes = shared ? Classes : new List<string>(Classes);
htmlAttributes.Classes = shared ? Classes : Classes != null ? new List<string>(Classes) : null;
}
else if (Classes != null)
{
@@ -127,7 +127,7 @@ namespace Markdig.Renderers.Html
if (htmlAttributes.Properties == null)
{
htmlAttributes.Properties = shared ? Properties : new List<KeyValuePair<string, string>>(Properties);
htmlAttributes.Properties = shared ? Properties : Properties != null ? new List<KeyValuePair<string, string>>(Properties) : null;
}
else if (Properties != null)
{

View File

@@ -53,10 +53,6 @@ namespace Markdig.Syntax
public static int FindClosestLine(this MarkdownDocument root, int line)
{
// Forces the preview window to scroll to the top of the document
if (line <= 3)
return 0;
var closestBlock = root.FindClosestBlock(line);
return closestBlock?.Line ?? 0;
}
@@ -89,7 +85,7 @@ namespace Markdig.Syntax
}
// If we are between two lines, try to find the best spot
if (lowerIndex >= 0 && lowerIndex < blocks.Count)
if (lowerIndex > 0 && lowerIndex < blocks.Count)
{
var prevBlock = blocks[lowerIndex - 1].FindClosestBlock(line) ?? blocks[lowerIndex - 1];
var nextBlock = blocks[lowerIndex].FindClosestBlock(line) ?? blocks[lowerIndex];
@@ -113,6 +109,18 @@ namespace Markdig.Syntax
return middle < 0.5 ? prevBlock : nextBlock;
}
if (lowerIndex == 0)
{
var prevBlock = blocks[lowerIndex].FindClosestBlock(line) ?? blocks[lowerIndex];
return prevBlock;
}
if (lowerIndex == blocks.Count)
{
var prevBlock = blocks[lowerIndex - 1].FindClosestBlock(line) ?? blocks[lowerIndex - 1];
return prevBlock;
}
return null;
}

View File

@@ -1,6 +1,6 @@
{
"title": "Markdig",
"version": "0.5.8",
"version": "0.5.12",
"authors": [ "Alexandre Mutel" ],
"description": "A fast, powerfull, CommonMark compliant, extensible Markdown processor for .NET",
"copyright": "Alexandre Mutel",
@@ -11,7 +11,7 @@
"projectUrl": "https://github.com/lunet-io/markdig",
"iconUrl": "https://raw.githubusercontent.com/lunet-io/markdig/master/img/markdig.png",
"requireLicenseAcceptance": false,
"releaseNotes": "> 0.5.8\n- Fix calculation of spans for nested blocks\n- Add methods for looking for a block from a position or for the closest line (typically used for syntax highlighting by MarkdownEditor)\n> 0.5.7\n- Fix issue with generic attributes extension not working properly and breaking parsing\n> 0.5.6\n- Improve pragma line output\n- Make MarkdownPipeline.Setup(renderer) public.\n> 0.5.5\n- Add same github class for task lists\n- Add pragma lines extension\n> 0.5.4:\nFix bug in HTML block parsing which could break parsing of remaining document",
"releaseNotes": "- Fix ArgumentNullException with MediaLinks extension in HtmlAttributes.CopyTo method\n",
"tags": [ "Markdown CommonMark md html md2html" ]
},
"configurations": {